Tuesday, August 24, 2004

JUnit work around for lost exceptions

Here's the scenario: a unit test throws an uncaught exception, but then so does tearDown(). What happens? TestCase.runBare() says:

public void runBare() throws Throwable {
    setUp();
    try {
        runTest();
    } finally {
        tearDown();
    }
}

See the problem? If tearDown() throws, then runBare() loses any exception thrown by runTest() (which runs your unit test). [See the Java Language Specification, §11.3.] Rarely is this what you actually want since the lost exception was the original cause of test error. The solution—override runBare():

public void runBare() throws Throwable {
    Throwable thrown = null;

    setUp();

    try {
        runTest();

    } catch (final Throwable t) {
        thrown = t;

    } finally {
        try {
            tearDown();

            if (null != thrown) throw thrown;

        } catch (Throwable t) {
            if (null != thrown) throw thrown;
            else throw t;
        }
    }
}

The idea is simple. Store the exception from runTest() and rethrow it after running tearDown(). Make sure to throw any exception from tearDown() otherwise.

UPDATE: My brain finally caught up with my fingers and I realize that the sample solution is unnecessarily complex. Better is:

public void runBare()
        throws Throwable {
    Throwable thrown = null;

    setUp();

    try {
        runTest();

    } catch (final Throwable t) {
        thrown = t;

    } finally {
        try {
            tearDown();

        } finally {
            if (null != thrown) throw thrown;
        }
    }
}

Monday, August 23, 2004

Hidden static methods

While debugging some slow code with a programming partner, we ran across a long series of statements like this:

new Foo(args).run();

Line, after line like this. What is going on? Apparently the original writer was thinking of something like command pattern without any sense of do/undo/redo. But what he wrote instead is another anti-pattern. Rather than littering the VM with a series of use-once instances just to invoke a method on them, he could have said:

Foo.run(args);

And by using a static method have been more clear that this was functional, not object-oriented code. Not every problem is a nail requiring the same hammer.

Saturday, August 21, 2004

Turning 90 degrees

An interesting problem: you have a depth-first process and need to turn it into a breadth-first one. How to proceed? A simple publish-subscribe message bus works single-threaded so when a message receiver publishes a new message in response, the new message is processed before the rest of the receivers of the first message have a chance to run. This leads to some confusing situations where message order is counter-intuitive.

Since everything is plain Java, I cannot use continuations for the activation records else I would just reorder them. Ah, but I can come close enough for this simple system. Consider these two data structures (in reality, they are immutable classes, but I shortened them to C-style structs for conciseness):

public class Binding {
    public Receiver recipient; // the target object for Method.invoke(Object...)
    public Method onReceive; // the method
}

public class ActivationSet {
    public Set<Binding> bindings; // JDK 5.0, plain Set for JDK 1.3 or JDK 1.4
    public Message message; // the argument for on Method.invoke(Object...)
}

Now the publish algorithm is quite simple given an instance variable of Queue<ActivationSet> for the channel:

public void publish(Message message) {
    Set<Binding> bindings = findSubscribers(message);

    if (bindings.isEmtpy()) return;

    // Check if we're first to publish
    boolean topContext = activations.isEmpty();
    // Queue our recipients
    activations.offer(new ActivationSet(bindings, message));
    // Let the top context handle recipients in queue-order
    if (!topContext) return;

    while (!activations.isEmpty()) {
        // activate() invokes onReceive for each binding in the set
        activations.peek().activate();
        // Be careful not to remove our own activation set prematurely;
        // otherwise the topContext check above won't work right
        activations.remove();
    }
}

The effect is to queue up the depth-first nature of recursive method calls and handle them in breadth-first order. The code is quite simple once the concept is clear.

Wednesday, August 18, 2004

Smarter exceptions

Very commonly I see code which puts data into the message of an Exception as a way to pass information. This was certainly the case with the original Exception class which provided no way to hold context. Recent JDKs fixed that with Exception.getCause(). But I didn't realize the general usefulness of this approach until reading the changes so far in JDK5 Beta2. After all, exceptions are just classes; they too can have more methods. In fact, this is just what UnknownFormatConversionException.getConversion made me see. Useful information passed on an exception to aid in recovery, logging, etc. is just the ticket.

The switch statement

A nice post by Tom McQueeney on the new varargs feature in JDK5 marred by one point:

if (params.length > 0) lastName = params[0];
if (params.length > 1) firstName = params[1];
if (params.length > 2) middleName = params[2];
if (params.length > 3) nickName = params[3];

if (params.length > 4) {
    throw new IllegalArgumentException("Constructor called with too many arguments");
}

Why the series of if statements? A simple switch statement with fall-through is more clear:

switch (params.length) {
case 4: nickName = params[3];
case 3: middleName = params[2];
case 2: firstName = params[1];
case 1: lastName = params[0];
    break;
default:
    throw new IllegalArgumentException("Constructor called with too many arguments");
}

Tuesday, August 17, 2004

Two testing tales, one bad, one good

Tale one, package mismanagement

Here is an anti-pattern:

java/blarfage/Foo.java:

package blarfage; public class Foo { }

java/test/blarfage/FooTest.java:

package test.blarfage; import junit.framework.TestCase; public class FooTest extends TestCase { }

What is wrong here—where is the anti-pattern? Do not put test classes in a different package than that of the class under test. It looks clean and logical, but try it for a while and the pain of it hobbles your testing. Many useful tricks vanish, chief among them package-scope methods for tweaking the class under test. Don't just take my word for it: try it on any moderate-sized project and see for yourself.

Tale two, useful IoC trick

Here is a handy trick for configuring a class under test: provide a separate, protected constructor just for testing.

java/blarfage/Foo.java:

package blarfage; public class Foo { private final Bar favorite; public Bar(final Drink beer) { this(new Bar(beer)); } protected Bar(final Bar favorite) { this.favorite = favorite; } }

test/blarfage/FooTest.java:

package blarfage; import junit.framework.TestCase; public class FooTest extends TestCase { private TestFoo foo; protected void setUp() throws Exception { foo = new TestFoo(createMockBar()); } private static final TestFoo extends Foo { private TestFoo(final Bar favorite) { super(favorite); } } }

The idea is this: Say Bar is complex or expensive—java.sql.Connection is a good example. The public constructor takes the argument for constructing the private, expensive or complex object; the protected constructor takes the actual expensive or complex object so that a test can extend the class under test and use that protected constructor.

This trick is especially handy when you do not have control of code using the class under test (else you might refactor the public constructor to take the expensive or complex argument directly as the protected constructor does).

Wednesday, August 11, 2004

Brittle relations

Much of the time a project needs decoupling between a database schema and the business model using the schema. This setup uses some kind of mapping file, often XML, to glue the two pieces together. However as the schema evolves, mismatches between schema and business model show up at run-time during testing. This is very annoying. If a project does not need the looseness afforded by a separate mapping file, I have a different suggestion. The most common design in this scenario is to have a persistence layer for database work and a domain layer above that representing the business model.

Consider an intermediate third layer—call it the schema layer—between the persistence and domain layers. This schema layer uses the persistence layer to exactly model the database schema rather than the business model. The domain layer uses the schema layer rather than call the persistence layer directly.

Why the extra layer? With the extra schema layer the mapping file vanishes. Use tools to generate the schema layer automatically by interrogating the database during the build. Then, as the schema evolves, incompatible syntactic changes (changes in columns or types, not changes in meaning) propagate into the code of the schema layer and manifest themselves as compile errors in the domain layer. This is a great aid during development. Compile-time errors are much easier to catch automatically than problems during testing, and strange reflection contortions are kept out of the business model.

Tuesday, August 10, 2004

Supporting old code

One JDK5 feature I particularly appreciate is the simplicity of the new foreach syntax, and the addition of an Iterable<T> interface in support. However, much of the JDK was written before even Iterator was around such as StringTokenizer. What to do? Write a wrapper, of course:

/**
 * <code>EnumerationIterator</code> is an {@link Iterator} wrapper for {@link
 * Enumeration}. {@link #remove()} is unsupported.
 */
public class EnumerationIterator <T> implements Iterator<T> {
    private final Enumeration<T> enumeration;

    /**
     * Constructs a new <code>EnumerationIterator</code> from the given
     * <var>enumeration</var>.
     *
     * @param enumeration the enumeration
     */
    public EnumerationIterator(final Enumeration<T> enumeration) {
        this.enumeration = enumeration;
    }

    /**
     * {@inheritDoc}
     */
    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }

    /**
     * {@inheritDoc}
     */
    public T next() {
        return enumeration.nextElement();
    }

    /**
     * {@inheritDoc}
     */
    public void remove() {
        throw new UnsupportedOperationException();
    }
}

/**
 * <code>EnumerationIterable</code> is an {@link Iterable} wrapper for {@link
 * Enumeration} to support JDK5 <em>foreach</em> syntax.
 */
public class EnumerationIterable <T> implements Iterable<T> {
    private final Enumeration enumeration;

    /**
     * Constructs a new <code>EnumerationIterable</code> for the given
     * <var>enumeration</var>.
     *
     * @param enumeration the enumeration
     */
    public EnumerationIterable(final Enumeration enumeration) {
        this.enumeration = enumeration;
    }

    /**
     * {@inheritDoc}
     */
    public Iterator<T> iterator() {
        return new EnumerationIterator<T>(enumeration);
    }
}

Now I can write this:

for (final String token : new EnumerationIterable<String>(new StringTokenizer("a:b:c", ":")))
    System.out.printnln(token);

Monday, August 09, 2004

Nice

Nice is a very attractive new Java-like language for the JVM. Xoltar has nice things to say about Nice, the language. I'm more than a little enchanted: much better type safety than Java, multimethods, closures, parametrics types, named parameters, tuples. Wow! And unlike Groovy, it really does look like Java after some weight-lifting. (I'm sorry, but I'm too attached to ;. Call me a "C" bigot, but it just looks wrong otherwise.)

I'm eager to give Nice a spin and perhaps use it a project. And the comparison of Nice and Groovy really isn't that fair — Nice is still pre-compiled into bytecode like Java, not scriptable like Groovy. There's plenty of need for both.

Trickiness with generics and reflection for methods

This caught me offguard at first:

public class Scratch { public static class Qux { } public static class SubQuux extends Qux { } public static class Foo <M extends Qux> { public void spam(final M meat) { } } public static class Bar extends Foo<SubQuux> { public void spam(final SubQuux meat) { } } public static void main(final String[] args) { try { for (final Method method : Bar.class.getMethods()) if ("spam".equals(method.getName())) System.out.println(method); } catch (Exception e) { e.printStackTrace(); } } }

So, just what does main print? The answer is fascinating:

public void Scratch$Bar.spam(Scratch$SubQuux) public volatile void Scratch$Bar.spam(Scratch$Qux)

Aha! Now I get it. Since the JDK5 compiler implements generics with type erasure, there needs to be a version of spam which takes the lowest possibly erased type, Qux, so that JDK1.4 runtimes can handle the method call. Crud. That messes up my reflection for messaging. However, the solution is staring right at me: volitile. Since there really is no such method as public void Scratch$Bar.spam(Scratch$Qux), the compiler synthesizes one and marks it as volitile. Nifty. Now I can filter those out with Modifier.isVolitile. No harm, no foul.

Sunday, August 08, 2004

Saturday, August 07, 2004

Messaging on one channel

For a simple application wanting to talk to itself, messaging on a single channel works well (or on two channels, input/output, to keep republishing from within an event handler from recursing). But to support class-hierarchy events instead of attribute-based ones calls for a decent data structure since you need reflection in both discovery and publishing.

The key code is:

public void publish(final Event event) { final Set<Receiver> receivers = new HashSet<Receiver>(); for (Class eventClass = event.getClass(); Event.class.isAssignableFrom(eventClass); eventClass = eventClass.getSuperclass()) for (final Pair<Receiver, Method> pair : getPairs(eventClass)) invokeOnce(receivers, pair.first, pair.second, event); }

Which looks up receiver/method pairs from an eventClass/pair map built from receiver subscriptions to the channel. InvokeOnce uses a set to remember if a receiver was already given the incoming event. Since publish starts with the most derived event class and works its way up towards the event base class, this ensures that only the receive method with the most derived event class argument is invoked.

You can have several receive methods, each with a different event class argument, and the best matching one is called. (For once, I am glad for single inheritance: this scheme would break with diamond inheritance.)

Wednesday, August 04, 2004

More on generics

Unfortunately, Sun's generics are not as similar to C++ templates as one might hope. For example, because of type erasure there is no difference between Foo<Bar> and Foo<Baz> in bytecode. That means that you cannot compile this appealing snippet:

class Peter implements Receiver<PaulMessage>, Receiver<MaryMessage> { // ... public void onEvent(final PaulMessage paulsCalling) { } public void onEvent(final MaryMessage marysKnocking) { } }

Why not? Because Receiver<PaulMessage> and Receiver<MaryMessage> both compile down to just Receiver JDK5 does not permit duplicate declarations in the implements list. This greatly lessens the usefulness of my previous post.

Monday, August 02, 2004

Messaging with generics

Talking to my programming pairmate, Gregor Hohpe, we discussed a Java project using messaging that distinguished messages by type rather than by id or topic. A drawback is that with JDK1.4 you need reflection or extra coding to make it work nicely. Generics in JDK5 take care of this:

public interface Receiver<E extends Event> { void receive(final E event); } public interface Channel<E extends Event> extends Receiver<E> { void subscribe(final Receiver<E> receiver); void unsubscribe(final Receiver<E> receiver); }

Here, receivers and channels are typed by event. By making events into a hierarchy—consider the advantages and disadvantages of the Exception hierarchy—, ipso facto receivers and channels mirror that hierarchy. (In this fragment channels are multiplexed receivers, one of many choices.)

One could also type receivers by channel:

public interface Receiver<E extends Event, C extends Channel<E>> { void receive(final E event); }

But this seems too tightly coupled.

Partial continuations

This is a clever idea: partial continuations. My language geek sense is tingling.