Monday, January 31, 2005

Sun to license IntelliJ IDEA?

Well, this sure is an interesting TODO list for JDK 6 ("Mustang") -- from the much larger list:

Application Stack
-----------------
* Buy or cross license a set of commercial applications that provide complete coverage of development needs. (Think MSDN license)
* Tools like JAR to EXE converter, Install Anywhere, IntelliJ IDEA, Atlassian JIRA, JGoodies, database swing controls, etc, should all be included in said Java Developer Network License. Components not necessarily developed by SUN should be included in this developer license sold per seat. (My company buys 1 MSDN license per developer with no known such license in the Java world).
* SwixML / XML Layout mechanism included in an application stack (discussed later)
* Java Help to be included in an application stack (discussed later)
* Critiqued by the community and versions feature frozen with bugfixes and updated regularly to include additional features.

According to Peter Kessler at Sun, this list catches a lot of what Sun is thinking of adding to Mustang (JDK 1.6) or Dolphin (JDK ?).

Cool beans!

Friday, January 28, 2005

Best Quote of the Month

Darren Hobbs states exactly how I feel about growing as a programmer:

I love it when I'm proven wrong, or make a mistake. It means there's still something more to learn.

Oops, null

I often rail against returning null as a marker or default value. I should listen to my own advice!

I'm working on a complex area of a program and deep within its structure is a method for finding the current main window frame. Originally, there might have been several top level frames so they were kept in a global list. But more recently the software moved to using one JVM for each main window, a good approach in light of the strong improvements in JDK 5 with sharing between JVMs.

Enforcing this rule, I wrote this:

public Frame getMainWindow() {
    final List<Frame> list = getTopLevelWindows();

    if (list.size() != 1)
        throw new IllegalStateException(
                "Other than one program on this VM");

    return list.get(0);
}

But this broke automated unit tests which exercise sections of the code calling getMainWindow. Tests do not have a main program window. Ok. So how did I fix it?

public Frame getMainWindow() {
    final List<Frame> list = getTopLevelWindows();

    if (list.size() > 1)
        throw new IllegalStateException(
                "More than one program on this VM");

    return list.isEmpty() ? null : list.get(0);
}

WRONG! I'm now returning null, but what if code is broken elsewhere and the list of top level windows is empty when it should have a member? I've created an NullPointerException at some random location instead of a specific failure. I've ignored my own advice.

What is the correct solution? Well, as the class containing this method implements an interface including getMainWindow and the unit test is already using a delegate instance of the interface, I restore the original version of the method, and implement a test-only version in the testing delegate:

@Override public Frame getMainWindow() {
    assertTrue(getTopLevelWindows().isEmpty());

    return null;
}

I now have correct behavior: running production code demands one and only one top level window per JVM, and unit test code demands none. I wish I had done this in the first place.

Thursday, January 27, 2005

SourceForge.net: XPlanner-IDEA version 0.6.5

Yet another cool plugin for IntelliJ IDEA: XPlanner. The latest improvements (as of 0.6.5):

  • Autopause working task after the specified period of inactivity
  • Open corresponding web page when double-click on task or story
  • Extended task filtering. Ability to view own tasks, own pending tasks, all tasks and not accepted (free) tasks
  • Ability to accept free task or reject own task

IntelliJ IDEA is for me still the best development environment for XP work.

Wednesday, January 26, 2005

Read-only properties in Java

C++ has the advantage over Java of supporting operator overloading. In particular, this makes straight-forward to implement read-only and write-only fields (data members in C++ parlance) that actually call back to methods (member functions) when accessed. C# has this feature as well. You cannot do that in Java, but you can at least provide a form of read-only fields.

Traditional Java uses bean-style getters and setters for field access, but there is a more elegant solution for data transfer-style objects:

public class ReadMe {
    public final String title;
    public final String body;

    public ReadMe(final String title, final String body) {
        this.title = title;
        this.body = body;
    }
}

That's it! This is yet another interesting use of the final keyword. The class fields are public, but because they are marked final, they cannot be modified once set and final fields must be initialized during construction. This prevents tampering, and makes the fields read-only. Using ReadMe is trivial:

public void displayReadMe(final ReadMe readMe) {
    createDialog(readMe.title, readMe.body).show();
}

Trivial — no getters or setters required. This idiom is flawed if you need to update the object, however, but field setters have plenty of drawbacks so this complaint is a mild one.

Monday, January 24, 2005

Throwing complex exceptions

In Java you sometimes have complex exceptions whose creation requires more than just a call to new. In those cases, I like to use a helper method to separate the the construction of the exception from the code which might throw the exception. (In fact my taste is to use such a helper anytime the exception is not ready in a single line of code. Sadly, IOException is such an exception when it has a cause: it is missing the full set of constructors that other descendents of Exception have.)

For such times which of these two snippets is preferred?

public void work(final Queue<PieceOfWork> workQueue)
        throws IOException {
    if (!doWork(workQueue))
        throw createWorkException(workQueue);
}

private WorkException createWorkException(final Queue<PieceOfWork> workQueue) {
    final WorkException e = new WorkException(getJobId());

    for (final PieceOfWork piece : workQueue)
        e.addPieceOfWork(piece);

    return e;
}

Or:

public void work(final Queue<PieceOfWork> workQueue)
        throws WorkException {
    if (!doWork(workQueue))
        throwWorkException(workQueue);
}

private void throwWorkException(final Queue<PieceOfWork> workQueue)
        throws WorkException {
    final WorkException e = new WorkException(getJobId());

    for (final PieceOfWork piece : workQueue)
        e.addPieceOfWork(piece);

    throw e;
}

Until recently I thought there was little difference between them but have changed my mind. Why? The first case is easy for static analysis tools to identify that there are two code paths, one of which throws an exception. The second case requires that the tool descend into throwWorkException and work out that one of the code paths throws an exception.

Although this is not much to ask of many of the more sophisticated static analysis tools, it is too much to ask of most of the tools bundled with common Java editors. IntelliJ IDEA, for example, does not pick up on this as it analysis your code as you type: it makes the sensible tradeoff of performance for completeness.

In fact, shallow static analysis is the reason javac flags this as an error:

public boolean checkCondition()
        throws SomeException {
    if (!cannotProceed())
        throwSomeException();
    else
        return true;

    // Missing return statement
}

Sad code, yes, but not uncommon, especially when the branches get very complicated so that it is not so obvious that they could be simplified.

Lastly, keeping the throw statement as close as possible to where the condition failed helps the most common static analysis tool of all: the human eye. When quickly browing others code, it is easy to miss the true code flow without the helpful throw keyword staring one right in the face.

Thursday, January 20, 2005

Whither aspectj?

This is cool news: the AspectJ and AspectWerkz projects are merging with annotations coming to the fore. I am very curious to see how this will work with JDK 5's apt tool. Apt (annotation processing tool) lets you process annotations at compile-time and extend the compiler with new syntax (as long as that syntax is annotations). I hope aspectj takes advantage of this clever system and uses annotation processors; a cursory look through the compiled jars doesn't seem to indicate that from the class names. It's a shame aspectj's download page does not provide the source to go with the binary installer.

Sunday, January 16, 2005

Wrong method with reflection

Try this:

public Method getUnaryMethod(final Class clazz,
        final String name, final Class parameterType)
        throws NoSuchMethodException {
    return clazz.getMethod(name, parameterType);
}

Looks easy, doesn't it? But:

private static class Overloaded {
    public Class foo(final Number number) { return number.getClass(); }
    // public Class foo(final Integer integer) { return integer.getClass(); }
}

void void testGetUnaryMethod() throws Exception {
    final Class expected = Integer.class;
    final Class actual = getUnaryMethod(Overloaded.class,
            "foo", expected).getParameterTypes()[0];

    assertEquals(expected, actual);
}

The test throws! To pass the test, uncomment the second definition of foo. Unfortunately, I'm working on a dispatch system and this sort of thing is death. Why? Because I cannot repeat with reflection this simple call:

new Overloaded().foo(new Integer(3));

There is a solution, though, replace getMethod with:

public static Method getMethod(final Class clazz,
        final String name, final Class parameterType)
        throws NoSuchMethodException {
    for (Class c = parameterType; null != c; c = c.getSuperclass())
        try {
            return clazz.getMethod(name, c);

        } catch (final NoSuchMethodException e) { }

    return clazz.getMethod(name, parameterType);
}

I look up the inheritance tree for parameterType until I find the first exact match via reflection and return that method. The catch block just lets me retry the lookup one branch higher in the tree. If I exhaust the tree, there is no match even with inheritance, in which case I retry the original lookup so as to throw the same exception as Class.getMethod(String, Class[]) would.

Now I can dispatch dynamically with reflection the same as would the Java runtime. The only drawback is that this simple algorithm only works to vary a single parameter type. For true multiple dispatch, I need a better algorithm to vary more than one parameter type and detect ambiguities: this would let me work methods with more than one argument.

Useless overload

Gotcha! — That's how I felt. I changed code like this:

final Worker worker = new Worker();
final Implement hoe = new Hoe();

worker.work((Hoe) hoe);

To remove the "obviously" useless cast. Well, no, not useless at all. I had overlooked Worker.work():

public class Worker {
    public void work(final Implement o) {
        // Generic work
    }

    public void work(final Hoe hoe) {
        // First do generic work
        work((Implement) hoe);
        // Now do hoe-specific work
        hoe.work();
    }
}

Argh! Of course, there are several much better ways to do this, and I could have changed the declaration of hoe instead of removing the cast. Putting the onus on the caller to pass in the right type of object is just grotesque. And by removing the cast, I broke the code.

I congratulate whomever devised that nasty trap, requiring two useless casts to work correctly and splitting them between the caller and the method no less! Unfortunately, it was purely accidental on their part.

Next time, please code this:

public interface Implement {
    public void work();
}

public class Worker {
    public void work(final Implement implement) {
        // First, generic work
        // Lastly, implement-specific work
        implement.work();
    }
}

Or, if you prefer, make Implement a class with a default, empty work() method. Just something that avoids uselessly useful casts and that requires ESP from the caller.

Thursday, January 13, 2005

The little nullity and a little final

Waldura writes a wonderful article on the final keyword in Java. For me also final is possibly my favorite keyword in the language. What I like best of all about it is its interaction with null. Consider this:

public class Mandatory {
    private final Law law;

    public Mandatory(final Law law) {
        if (null == law)
            throw new NullPointerException();

        this.law = law;
    }

    public Law getLaw() {
        return law;
    }
}

Here law is mandatory, that is, the class never works right without a law. Note the idiom in the constructor. Once the constructor finishes, the class is guaranteed to be null-proof: there's no setter to foul it up; the field is marked final so it won't even compile if you forget to set law in all constructors. No one calling getLaw() need ever check it for nullity. I cannot tell you how tired I get of fixing code where the author does not understand the frequent problems null generates!

And the other way with an optional field instead of mandatory as above:

public class Optional {
    private Virtue virtue;

    public Optional() {
    }

    public Optional(final Virtue virtue) {
        setVirtue(virtue);
    }

    public void setVirtue(final Virtue virtue) {
        this.virtue = virtue;
    }

    public boolean hasVirtue() {
        return null != virtue;
    }

    public Virtue getVirtue() {
        if (null == virtue)
            throw new NullPointerException();

        return virtue;
    }
}

See how much more complicated Optional is than Mandatory? Once you have optional members of a class, it drastically complicates matters. There are extra constructors (and I'm ignoring the whole notion of default values). There is the hasX()/getX() pair to catch accident use of null as early as possible. There is the setter. And we have lost the benefit of final.

The lessons? Avoid optional members (this is quite different, by the way, from the lazy evaluation idiom). Combine final with preventing nullity. The Java language encourages this with the elegance of the mandatory-field class v the clumsiness of the optional-field class.

Write elegant code, not clumsy code.

UPDATE: Reedited for clarity; too much late-night fractured grammar.

Saturday, January 08, 2005

Do or die

I believe that the Do-or-die principle is the strongest protector of good software, and the greatest preventative against mystery bugs, convoluted logic and tortuous coding. What do I mean?

Do-or-die is simple: either an operation succeeds or it raises an exception. When you call a do-or-die method, any normal code path relying on the results of that method have a guarantee for sanity—there are no problems to check for or deal with in the normal code path. The abnormal code path coping with the raised exception handles all problems. (Contrast this with languages lacking exceptions.) This means:

  1. Any procedure always returns void; no boolean returns that require checking for success or failure. Just call the procedure and be done with it.
  2. Any function always returns a valid object; no null returns that require nullity checks. Just capture the return and use it as expected.

Because of do-or-die, tremendous amounts of work, thinking, testing, coding and bug hunting are eliminated. Code is vastly more readable without a thicket of checks, nexted if/else blocks and null handling. Clarity and sanity is a natural product of do-or-die. I can think of no other idiom with as high a payoff in simplicity of notion to size of benefit.

Friday, January 07, 2005

Decreasing functor syntax in Java

Functor, closure, functional, operator, executor: there are many names in Java for the same thing, a class which encapsulates a single generic operation than can be handed around like the unsyntactic anonymous function available in other languages.

For a while, I've used some variation of this model:

public interface Closure {
    void execute();
}

Typical use:

new Closure() {
    public void execute() {
        System.out.println("Ni!");
    }
}

This is perfectly adequate when you create such a thing and pass it around. But what if you are looking to use it immediately? I sometimes see this:

new Closure() {
    public void execute() {
        System.out.println("Ni! Ni!");
    }
}.execute();

The example is contrived, but the principal is easy to grasp: there is a shorter way to do this. Try instead:

public abstract class ImmediateClosure {
    protected ImmediateClosure() {
        execute();
    }

    public abstract void execute();
}

new ImmediateClosure() {
    public void execute() {
        System.out.println("Ni! Ni! Ni!");
    }
};

Shorter. That's all I'm saying.

Tuesday, January 04, 2005

Testing without tests

Like some horrible nightmare come back to haunt the daytime, I'm working on an extensive, mixed-language code base lacking unit tests. XP likes to promote courage—the courage to make changes—, but without unit tests I feel like a tight-rope walker with no net to catch me when I fall. And sure enough, I fell this past week.

Our code base has some serious poor design decisions, many of which are old and embedded in the psyches of existing staff. No one defends the errors, but everyone is afraid to cut them out for fear that the operation may be a success, but the patient dies anyway. I began some cutting last week, trying to untagle a weave of deeply-nested if/else branches, protected data members, fake data objects and everpresent tests for null. Every single one of these is a bad code smell.

It comes as no surprise that I failed to repair all the damage I caused in my changes given that there were no unit tests for the affected code. I added unit tests where I worked directly, but that left large swaths of code untested elsewhere, much of it lurking and unseen in unrelated (but actually related) sections of our system. I've since added more tests and fixed the resultant defects, but in the meanwhile we had about a week of failed Q/A testing in areas no one thought had changed.

XP also eschews code ownership and programmer ego, so I owned up quickly in a public email that I thought I may have caused the problems with my changes, and that I was looking for someone to review code with me to find the trouble spots. This did get one senior programmer to review one of my changed files and to note that he could see nothing wrong with it, but it also prompted him to publically rebuke me when I asked him for a code review of my new changes that fixed one of the problems. He was afraid his name would be tarred by my mistakes. This makes for a difficult environment to work in.

Courage, I remind myself, courage. And more unit tests.

Wednesday, December 29, 2004

Using apt

While exploring the new JDK 5 tool apt (annotation processing tool), I figured out how to write new source code that is compiled into my build tree along side my regular Java sources. Here is a trivial example.

First, I need an annotation processing factory (I ignore imports and such throughout):

public class MyAnnotationProcessorFactory
        implements AnnotationProcessorFactory {
    public Collection supportedOptions() {
        return Collections.emptySet();
    }

    public Collection supportedAnnotationTypes() {
        return Collections.singleton(
                getClass().getPackage().getName() + ".*");
    }

    public AnnotationProcessor getProcessorFor(
            final Set atds,
            final AnnotationProcessorEnvironment env) {
        return new MyAnnotationProcessor(atds, env);
    }
}

Second is to have an annotation processor:

public class MyAnnotationProcessor
        implements AnnotationProcessor {
    private final Set atds;
    private final AnnotationProcessorEnvironment env;

    MyAnnotationProcessor(final Set atds,
            final AnnotationProcessorEnvironment env) {
        this.atds = atds;
        this.env = env;
    }

    public void process() {
        for (final AnnotationTypeDeclaration atd : atds) {
            for (final Declaration decl
                    : env.getDeclarationsAnnotatedWith(atd)) {
                final String typeName = decl.getSimpleName() + "Example";
                final String fullTypeName = getPackageName() + "." + typeName;

                try {
                    final PrintWriter writer
                            = env.getFiler().createSourceFile(fullTypeName);

                    writer.println("package " + getPackageName() + ";");
                    writer.println("public class " + typeName + " {");
                    writer.println("}");

                } catch (final IOException e) {
                    throw new RuntimeException(fullTypeName, e);
                }
            }
        }
    }

    private String getPackageName() {
        return getClass().getPackage().getName();
    }
}

Last is to tell apt how to fit it all together (I'm using a Maven-style layout):

apt -cp target/classes
    -s target/gen-java -d target/gen-classes
    -target 1.5 -factorypath target/classes
    -factory MyAnnotationProcessorFactory
    src/java/AnnotatedExample

When I run the apt command, given suitable annotations in AnnotatedExample, it pulls them out, instantiates my annotation processor via my factory, and hands them to process() therein. The key is to use com.sun.mirror.apt.Filer, a class in $JAVA_HOME/lib/tools.jar. There are no online javadocs that I have found yet. Here is what the JDK 1.5.0_01 sources say about the Filer interface:

This interface supports the creation of new files by an annotation processor. Files created in this way will be known to the annotation processing tool implementing this interface, better enabling the tool to manage them. Four kinds of files are distinguished: source files, class files, other text files, and other binary files. The latter two are collectively referred to as auxiliary files.

There are two distinguished locations (subtrees within the file system) where newly created files are placed: one for new source files, and one for new class files. (These might be specified on a tool's command line, for example, using flags such as -s and -d.) Auxiliary files may be created in either location.

During each run of an annotation processing tool, a file with a given pathname may be created only once. If that file already exists before the first attempt to create it, the old contents will be deleted. Any subsequent attempt to create the same file during a run will fail.

My next step is to glue velocity into my processor so I can use templates for writing the new Java sources.

Tuesday, December 28, 2004

The future in futures

Brian McCallister has started a great set of posts on futures. This fits in perfectly with my work with Gregor Hohpe on Mercury, a light-weight messaging library for Java. Brian explains futures:

Futures are really nice conceptually, and provide for much more natural and easy to use concurrent design than Java style threading and monitors. It relates to a lot of functional programming concepts, but the key idea is that a future represents an evaluation which has not yet occured. Maybe it is being lazily evaluated, maybe it is being evaluated concurrently in another thread.

Java has no futures, but I do fake closures using reflection and a sort of distended proxy. The core of Mercury is that when code publishes a message to a channel, it is not immediately delivered. Instead, the channel records an activation record (binding) and begins reordering the records before activating the bindings. This lets Mercury have breadth-first message delivery instead of depth-first, and circumvents the effects of using a call stack in a messaging system.

Gregor's excellent Enemy of the State post describes the thinking in more detail along with some ramifications. I'm just the humble mechanic who coded the library. :-)

UPDATE: I just got an anonymous comment pointing me to java.util.concurrent.Future. Zowie! That's a cool thing to find.

Sunday, December 26, 2004

Using JDK 5 varags for testing

One JDK 5 feature I have started using to clean up my testing is varargs, the ... (or for the entity-aware). It is particularly elegant to turn this:

public void testWidgetProcessor() throws Exception {
    final Widget expected1 = createWidget(), expected2 = createWidget();

    processor.swallow(new Widget[]{
        expected1,
        expected2
    });

    assertWidgetsGained(new Widget[] {
        expected1,
        expected2
    });
}

Into this:

public void testWidgetProcessor() throws Exception {
    final Widget expected1 = createWidget(), expected2 = createWidget();

    processor.swallow(expected1, expected2);

    assertWidgetsGained(expected1, expected2);
}

And even better:

public void testWidgetProcessorHandlesTrivialCase() throws Exception {
    assertWidgetsGained(); // nothing swallowed, nothing gained
}

XOM Design Principles

A very, very interesting article, XOM Design Principles, on Java library design. What took me particularly off-guard was the preference for classes over interfaces. The argument over this point presents much to digest.

Sunday, December 19, 2004

What are Java annotations?

This must be described elsewhere, but a quick Googling didn't give it to me. A little experimentation reveals to me that JDK 5.0 annotations are dynamic proxies under the hood.

To find this out, I made an annotation named @annotate and exammined annotation.class; it revealed itself to be an interface. I then decorated a method with @annotate, got the Method with reflection, pulled the appropriate annotation class off with getAnnotation(annotate.class).getClass() and examined that: dynamic proxy, $Proxy3(java.lang.reflect.InvocationHandler).

I wonder how I can use this knowlege for some real Java-fu.

UPDATE: An even stronger answer: Proxy.isProxyClass(Class) returns true on the method annotation class, and the proxy invocation handler is a sun.reflect.annotation.AnnotationInvocationHandler. Good thing Sun provides source for the non-public bits.

Saturday, December 18, 2004

A taste of things to come

Now to make it work!

/**
 * Marks a method with a <em>pre-condition</em>.  The required annotation
 * {@link #value()} is a <code>boolean</code> condition.  The optional
 * {@link #message()} is used in {@link DBCException} if the condition
 * fails.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface pre {
    boolean value();

    String message() default "";
}

/**
 * Marks a method with a <em>post-condition</em>.  The required annotation
 * {@link #value()} is a <code>boolean</code> condition.  The optional
 * {@link #message()} is used in {@link DBCException} if the condition
 * fails.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface post {
    boolean value();

    String message() default "";
}

/**
 * Marks a method with an <em>invariant</em>.  The required annotation
 * {@link #value()} is a <code>boolean</code> invariant.  The optional
 * {@link #message()} is used in {@link DBCException} if the invariant
 * fails.
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface inv {
    boolean value();

    String message() default "";
}

UPDATE: I'll have to think about this longer. Turns out that annotations only accept constants or expressions which evaluate to constants. A constant pre-condition isn't very interesting.

Friday, December 17, 2004

Looking up the location of a class file

IBM's JAR Class Finder reminds me of a snippet of utility code I wrote for PCGen which used a clever trick to find the location on disk of the definition for a given class, either a jar or a directory in the classpath:

new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().normalize())

The only drawback: for the JDK itself the protection domain has a null code source. Since Class.getProtectionDomain() relies internally on a native method to create the protection domain, I'm unsure if this is a bug or intended behavior. It certainly isn't documented in the javadocs. I consider this a bug, but others disagree and it has changed between JDK versions.

Thursday, December 16, 2004

Clever IDEA

I just noticed very clever behavior by IntelliJ IDEA 4.5.3 on Windows. I ran a junit test that crashed the test JVM from badly behaved JNI code. Unfortunately, this caused the JVM for IDEA itself to eventually exhaust memory and crash. IDEA handled this well, informed me of the problem, and gracefully shutdown.

The cool part: when I launched it again, it ran the console window for the LAX launch wrapper. Normally this does not appear so that you just have the main application window, but the console emits all sorts of interesting information useful to someone developing IDEA. Presumably, had the crash I mentioned been IDEA's fault, I could use that information to help IntelliJ fix the bug.

Further, I closed IDEA normally and relaunched it. This time it come up normally with no extra console window. The console window feature is only triggered by a crash in IDEA. Nifty!

Wednesday, December 15, 2004

Messaging with annotations

I'm working on a talk for SD West 2005 with a former coworker, Gregor Hohpe of ThoughtWorks. We coded a simple Java messaging system for single VM apps. Most messaging systems are based on messages segregated by subject, usually a String field. Our system though is type-based. Messages implement (or extend) Message, and receivers provide methods receive(Message) to receive published messages.

The dispatch loop makes extensive use of reflection to find a "best matching" method. If you have:

public class FooReceiver extends Receiver {
    public void receiver(final Message message) { }

    public void receiver(final FooMessage message) { }
}

Then if a FooMessage (or a subtype) comes along, the better matching method receives the message, otherwise the more general method does.

But I have found a better way: annotations :-) Consider:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MessageHandler {
    Class[] value();
}

This bit of annotation magic lets me say this in my receiver class:

public class FooReceiver {
    @MessageHandler({Message.class})
    void receiveAllTypes(final Message message) { }

    @MessageHandler({FooMessage.class})
    void receiveFooTypes(final FooMessage message) { }
}

Now if a FooMessage comes along, both methods see the message: logically, there is no method overloading to consider since they are differently-named methods. But this has several other advantages:

  • No need to extend or implement anything; just annotate the methods
  • Methods can have better names than just receive; it's the annotation, not the name, which counts
  • Interestingly, you can write methods to handle disjoint types:
public class DisjointReceiver {
    @MessageHandler({FooMessage.class, BarMessage.class})
    void handleEitherFooOrBarType(final Message message) { }
}

Nifty — there is no need for FooMessage or BarMessage to be related types. In fact, to carry the disjunction one step further, I could dispense entirely with the Message class! Hmmm...

UPDATE: I fixed the bad links. That's what I get for blogging while woozy with flu.

Maven and test cases

I have a problem with maven I am hoping someone knows the best solution to. As is typical with Java projects using maven, I have separate src/java and src/test trees and they compiles to build/classes and build/test-classes, respectively. When I build a distribution jar, maven zips up build/classes into the jar (along with LICENSE.txt and any resources). This much I know and appreciate.

However, my project uses JUnit for testing, so I have *Test classes, one for each class under test. And my project provides *TestCase base classes for other test classes to extend. The test case classes add functionality to junit.framework.TestCase. These live under the src/test tree since they are only used for testing, and they are dependent on junit-3.8.1.jar. Of course, they compile to build/test-classes.

But since the dist goal only packages up build/classes, the test case classes do not become part of my distribution jar. And I want to package them for distribition. Oops.

For now, I've moved the test case classes from src/test to src/java so that maven will bundle them in the distribution jar, but I feel awkward doing that.

Is there some way to teach maven to pull src/test/**/*TestCase.java classes from build/test-classes into the distribution jar, but no other test classes?

Delegation, a problem and solution

I'm adding unit testing to existing code and encounter this problem:

public class Foo {
    private static Foo SINGLETON;
    private static Trouble TROUBLE;

    private Foo() { }

    public Foo newInstance() {
        if (null == SINGLETON) SINGLETON = new Foo();
        return SINGLETON;
    }

    public Trouble getTrouble() {
        if (null == TROUBLE) TROUBLE = new Trouble();
        return TROUBLE;
    }

    public void doSomething() {
        getTrouble().doSomethingElse();
    }
}

Callers are expected to write Foo.newInstance().doSomething(). Fair enough. For unit testing, I want to replace SINGLETON with a stub or mock object that extends Foo in setUp() and put it back to null in tearDown(). Foo is not under test, but classes I am testing call to it and I need to control the interaction.

What about TROUBLE? It is a complex object with its own behavior, so I need to stub or mock it as well. But here's the rub: I don't have control over its source. It could be a SWIG-generated wrapper for JNI, or from a third-party jar I lack the sources to. And the class looks something like this:

public final class Trouble {
    public void doSomethingElse() { }
}

Oops! No extending for me. what to do? It is time to rely on delegation.

First, extract an interface from Trouble, say Troubling, which contains all the public methods in Trouble. We cannot change Trouble to implement Troubling, but I'll overcome that in a moment.

Second, update Foo and all callers of Foo.getTrouble to refer to Troubling and not Trouble. This decouples them from dependency on Trouble.

Third, create a new class which implements Troubling and delegates to Trouble:

public class NoTrouble implements Troubling {
    private final Trouble trouble;

    public NoTrouble(final Trouble trouble) {
        this.trouble = trouble;
    }

    public void doSomethingElse() {
        trouble.doSomethingElse();
    }
}

Lastly, update Foo to use NoTrouble instead of Trouble:

public class Foo {
    private static Foo SINGLETON;
    private static Troubling TROUBLE;

    private Foo() { }

    public Foo newInstance() {
        if (null == SINGLETON) SINGLETON = new Foo();
        return SINGLETON;
    }

    public Troubling getTrouble() {
        if (null == TROUBLE) TROUBLE = new NoTrouble(new Trouble());
        return TROUBLE;
    }

    public void doSomething() {
        getTrouble().doSomethingElse();
    }
}

We're following the ancient dictum, any problem can be solved by introducing an extra level of indirection. Foo was already delegating doSomething() to Trouble; we just replaced that relationship with an extra level of delegation, Foo to NoTrouble to Trouble. Now I can mock or stub NoTrouble without needing access to Trouble.

Go have a peanut butter sandwich.