Shane Bell

My thoughts on... well, anything that springs to mind really.

Wednesday, May 30, 2007

 

This blog has moved!

This blog has moved to here.

The new rss feed can be found at blog.onlysimpler.com/rss.xml

Tuesday, November 21, 2006

 

SchemaSpy

If you're working on a project that uses a relational database (I don't think I've ever worked on one that didn't) then you really need to check out SchemaSpy. It's a great tool that automatically produces a complete overview of your schema - diagrams and all.

Here's a sample of what it can produce.

It's very useful for navigating around the tables and seeing relationships between them. It even does some analysis of your schema to identify any potential problems.

One thing to note is that it takes a static "snapshot" of your schema. The information is not produced in real time, so you'll need to re-run the program now and again to keep it up to date.

The application itself is a single jar file that you can execute from a command line. You'll also need a JDBC driver so it can talk to your database.

Finally, in order to produce all the fancy diagrams, you'll need the "dot" executable from Graphviz. Check the docs for more info on that.

And best of all - it's free (as in beer).

Monday, October 23, 2006

 

Subversion - the 30 second guide

Setting up a Subversion repository is one of those things that I can never seem to remember how to do. I guess that's because you tend to do it once at the start of a project and it might be 6 months before you need to do it again. And by that time you've forgotten how to do it and need to go search through the docs.

So here is a very quick guide to setting up a new repository.


  1. Create a new repository.

    $ svnadmin create path_to_repository


  2. Modify the svnserve.conf and passwd files.


  3. Create new project directory.

    $ svn mkdir svn://path/to/repo/myproject


  4. Create a sub-directory for the trunk (you can create branches and tags later if necessary).

    $ svn mkdir svn://path/to/repo/myproject/trunk


  5. Checkout the project and start working.

    $ svn checkout svn://localhost/repository/project/trunk .


Thursday, September 28, 2006

 

Synchronized Collections in Java

This is just a quick word of advice to anyone out there writing threaded code with collections. I recently had to fix an old neglected web application that was having some serious threading issues and came across this little gem.

Creating a synchronized collection is as easy. All you need to do is...


List<Long> myList = Collections.synchronizedList(new ArrayList<Long>());


However, be careful when iterating over the collection. You still need to manually synchronize code that iterates over it, even though the collection itself is synchronized. Standard operations like adding or removing elements from the collection are thread-safe and will behave as expected in a multi-threaded environment. But iterating is not as simple.

If you want to iterate over a collection that will potentially be accessed by other threads simultaneously, always synchronize on the list itself. ie:


List<Long> myList = Collections.synchronizedList(new ArrayList<Long>());

// thread safe code
synchronized(myList) {
for (Long l : myList) {
// do something with l here
}
}


Failure to synchronize on the collection can cause all kinds of unexpected behaviour. Typically you'll get a ConcurrentModificationException if the collection is modified while you're iterating over it, but there are no guarantees. And that's the problem. An application that falls over and dies is bad, but at least you know it's broken. An application that continues on merrily despite being broken is a very bad thing!

Wednesday, September 27, 2006

 

Closures In Java

There's been some talk recently about adding closures to the Java language.

I've spent quite a bit of time writing Ruby code recently, and it's amazing how useful closures and code blocks can be. They're one of those things - once you know how to use them, you start noticing all kinds of places in your code that could be solved using closures. It's like when you learn a definition of a new word and suddenly you start hearing it in conversations everywhere.

It will be interesting to see how the proposal turns out, but unfortunately we'll have to wait until Java 7 to use them. Considering how many people still haven't made the move to Java 5, this could be a while for some.

In the meantime, there are a number of hacks that you can use to provide similar functionality to a closure. In fact, Apache Commons Collections even has some built in classes that provide closure-like functionality.

But if you need something quick and dirty, this should do the trick.

First, define a simple interface to represent a closure:


public interface Closure {

public void execute(Object o);

}


The next step is to create a method that calls the execute method of the closure. The following example iterates over a collection and calls the execute method on every object.


public static void execOnEach(Collection collection, Closure closure) {
for (Object o : collection) {
closure.execute(o);
}
}


Finally, we write some code that uses the closure interface to execute a block of code on every object in a collection. We do this by creating an anonymous instance of the closure.

This example uses a collection of StringBuffer objects. The first call to execOnEach() converts each buffer to upper case, while the second call reverses the contents of the buffers.


public static void main(String[] args) {

Collection c = new ArrayList();
c.add(new StringBuffer("abcdefg"));
c.add(new StringBuffer("hijklmn"));
System.out.println("c = " + c);

// capitalise everything
execOnEach(c, new Closure() {
public void execute(Object o) {
StringBuffer buffer = (StringBuffer) o;
buffer.replace(0, buffer.length(), buffer.toString().toUpperCase());
}
});

System.out.println("c = " + c);

// reverse the strings
execOnEach(c, new Closure() {
public void execute(Object o) {
StringBuffer buffer = (StringBuffer) o;
buffer.reverse();
}
});

System.out.println("c = " + c);
}


This is a pretty trivial example, but you get the idea.

Friday, August 25, 2006

 

Exposing Your Privates

If you've ever written any serious unit tests for your code then you'll know that testing private methods can be a bit tricky. The only class that has access to a private method is the class that defines it. So how are you supposed to test it from another class that doesn't have visibility of the method?

One solution would be to NOT declare it as private. This would work, but it's not much of a solution. Methods are made private for good reason and you can't just go around changing their access to suit your testing needs. That's just wrong.

Purists would say that you should test private methods via the public methods that expose their functionality. Purist say a lot of crap.

Seriously though, sometimes you need to test a private method, and there just no way around it. Fortunately there's easy solution to the problem. A bit of reflection should do the trick.


/**
* Invokes a private method on a class or object. This method
* can invoke static methods on classes, and instance methods
* on objects.
*
* When invoking an instance method, the instance of the object
* must be passed as the first parameter. For static methods,
* this parameter can be null.
*
* @param object the object to invoke the method on (this is
* only applicable for instance methods, can be null
* for static methods).
* @param clazz the class of object.
* @param methodName the name of the method to invoke.
* @param parameters parameters passed to the method.
* @return result from the method or null if method returns void.
*/
public static Object invokePrivateMethod(Object object,
Class clazz,
String methodName,
Object... parameters) {

// build an array of parameter types
Class[] params = new Class[parameters.length];
for (int i = 0; i < parameters.length; i++) {
params[i] = parameters[i].getClass();
}

Object result = null;

// try to execute the method
try {
Method method = clazz.getDeclaredMethod(methodName, params);
method.setAccessible(true);

// are we invoking a static method or an instance method?
if (object != null) {
result = method.invoke(object, parameters);
} else {
result = method.invoke(clazz, parameters);
}
} catch (Exception e) {
e.printStackTrace();
}

return result;
}


The javadoc comment pretty much explains it, but here's a quick example that you shows how to use it.

Let's assume we have a class called Greeter that looks like this.


public class Greeter {

// a private instance member
private String name;

// public constructor
public Greeter(String name) {
this.name = name;
}

// static method that responds with a cheery greeting
private static String sayHello(String name) {
return "Hello " + name;
}

// instance method that responds with a cheery greeting
private String sayHello() {
return "Hello " + this.name;
}
}


Notice it has two private methods. One is a static method, the other is an instance method. Using invokePrivateMethod() that we defined earlier we can invoke these methods as follows.


// invoke a static method
invokePrivateMethod(null, Greeter.class, "sayHello", "Shane");

// invoke an instance method
Greeter greeter = new Greeter("Shane");
invokePrivateMethod(greeter, greeter.getClass(), "sayHello");


Now you really have no excuse for not writing unit tests ;)

Thursday, August 24, 2006

 

I'm Back

It's been a while, but I'm back.

No real excuse, other than the fact that I've been out enjoying the summer. But now that that's over you can expect to hear a bit more from me, hopefully regularly.

I've added a few new books to my ultimate reading list. You'll notice a couple of Ruby books have snuck in there. I'll go into that in a bit more detail in an upcoming post.

I've also added some more random technical things that I always seem to forget.

That's it for now, but I've got lots of new things in the pipeline so stay tuned.

Wednesday, May 31, 2006

 

Random Technical Stuff

This post is just a collection of random technical stuff that I can never seem to remember. I find myself regularly wasting loads of time researching something that I did just a few months (or even weeks) ago. So I figured I'd put together my own collection of technical bits and pieces here so I can refer back to them as I need them.

It's also a place for me to collect all my templates for development (things like Ant scripts, Struts config files, etc).

I'll try and update this list regularly.

Java


Oracle


SSH




Tuesday, March 21, 2006

 

Oracle SQL Developer

Oracle have just released a new visual SQL that is well worth a look. I'm big fan of Toad, but you have to pay for it because the free version stops working after 30 days. Oracle's new tool is free, and everybody likes free stuff.

It does a pretty good job of all the standard stuff you ever need to do when working with a database and it has some nice visual tools and wizards. It's one big downfall is that it only works on version 9.2.0.1 and up of their database, so if you're running an older version you'll have to use something else. But overall it's a pretty solid tool.

Take a look at Oracle SQL Developer for yourself.

Thursday, March 16, 2006

 

Some more books

Below is the my personal "ultimate reading list". All of them sit on my bookshelf either electronically or physically and are well worth the read.

These books are mainly concerned with software development at a conceptual level. However, there are a few hardcore technical books in there too. Basically these books got me where I am today, hopefully you'll find them useful too.

I'll add to this as I think of more, but this is a good start.



And here are a few links to some free online books...

Archives

October 2005   November 2005   December 2005   January 2006   March 2006   May 2006   August 2006   September 2006   October 2006   November 2006   May 2007  

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]