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.
- Create a new repository.
$ svnadmin create path_to_repository
- Modify the svnserve.conf and passwd files.
- Create new project directory.
$ svn mkdir svn://path/to/repo/myproject
- Create a sub-directory for the trunk (you can create branches and tags later if necessary).
$ svn mkdir svn://path/to/repo/myproject/trunk
- 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.
JavaOracle
- To create an Oracle synonym...
create synonym <name> for <schema>.<object>
- To select the next value in an Oracle sequence...
select <sequence_name>.nextval from dual
- To find out the standard TNS details for a global database name run the NAMESCTL command and execute the following query at the prompt...
query <global_db_name> A.SMD
- To add a constraint to a table...
alter table <schema_name>.<table_name> add (constraint <key_name> primary key (<columns>))
- To run a sql script from sqlplus (and pass the parameter 123)...
SQLPLUS <username>/<password>@<dbname> @script.sql 123
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
Archives
October 2005
November 2005
December 2005
January 2006
March 2006
May 2006
August 2006
September 2006
October 2006
November 2006
May 2007

Subscribe to Posts [Atom]