Wednesday, December 27, 2006

Making a one-jar with Maven

(This is a lengthier post than usual. You can skip forward to the finished example, if you like.)

UPDATE:The One-JAR author comments:

Nice article, thanks for using (and persisting with) One-JAR. I just released a new version (0.97), checkout http://one-jar.sourceforge.net/

The one-jar-maven plugin has been updated with this new release, and there is also a new project in the CVS repository showing how to use maven2 to build (http://one-jar.cvs.sourceforge.net/viewvc/one-jar/one-jar-maven/)

A major part of this release was making it easier to set up One-JAR projects, to which end there is an application generator (one-jar-appgen) which will create a basic One-JAR directory tree, with support for building under Eclipse/Ant, and which contains a JUnit test harness. I’d be interested in hearing your thoughts on this if you’re still working with the product.

One-JAR

I recently came across Simon Tuffs' One-JAR Java project. It uses a custom "boot" classloader to place whole JARs within JARs and fix up the classpath accordingly.

The standard classloader will not do this and requires that supporting JARs be external to each other. So if I have Main.jar with dependency log4j.jar where Main.jar holds the main entry point—hm.binkley.Main, say—I cannot bundle log4j.jar into Main.jar but must distribute it alongside separately.

This has no effect on running Java, but changes distribution as I can no longer provide a single file (Main.jar in this example) for others to run.

Contrast these two ZIP files:

  • Foo-1.0-with-one-jar.zip:
    • foo-1.0/Main.jar
    • foo-1.0/README
  • Foo-1.0-without-one-jar.zip:
    • foo-1.0/Main.jar
    • foo-1.0/log4j.jar
    • foo-1.0/README

In this example, it does not seem to make a lot of difference; but when a project pulls in several Jakarta Commons JARs, several other open-source JARs, and several in-house, proprietary JARs, it becomes very obvious that distribution is an issue. One project I work on has a java command line between 5000 and 6000 characters long because of external jar dependencies in the classpath.

A traditional solution is to repack all the classes, internal and external, in to a single über-JAR, losing the independent qualities of each JAR including interesting MANIFEST.MF entries.

One-JAR solves this elegantly by packing everything into one JAR without unpacking the dependencies. My command line becomes just:

$ java [-options] -jar Main.jar

Ant

An Ant script for One-JAR is simple. One-JAR requires that you pack your original Main.jar into the final, single JAR along with dependencies:

  • main/Main.jar
  • lib/log4j.jar

They pack in with the One-JAR classes.

One-JAR then provides a custom classloader and alternative main entry point to glue it all together and a custom URL for classloading, onejar:.

As One-JAR provides you with a prototype outer JAR, all you need do is update the prototype, adding in main/Main.jar and lib/log4j.jar with Main.jar!main/Main.jar!META-INF/MANIFEST.MF unchanged:.

Manifest-Version: 1.0
Main-Class: hm.binkley.Main
Class-Path: log4j.jar

Leave unchanged the Main.jar!META-INF/MANIFEST.MF provided in the prototype:

Manifest-Version: 1.0
Main-Class: com.simontuffs.onejar.Boot

(Note that the first Main.jar is the prototype copied from one-jar-boot-0.95.jar, provided with the One-JAR download, and the second Main.jar is your original executable JAR.)

One-JAR follows the convention that your "real" JAR is in main/ and all dependency JARs are elsewhere within your single, distributable JAR. Nothing is unpacked.

The jar task handles this ably:

<target name="one-jar" depends="jar" description="Build one ONE-JAR">
    <property name="onejardir" location="${pom.build.directory}/one-jar"/>
    <mkdir dir="${onejardir}/main"/>
    <mkdir dir="${onejardir}/lib"/>

    <copy tofile="${onejardir}/${jarfile}"
            file="lib/one-jar-boot-0.95.jar"/>
    <copy todir="${onejardir}/main"
            file="${pom.build.directory}/${jarfile}"/>
    <copy todir="${onejardir}/lib" flatten="true">
        <fileset dir="lib" includes="*.jar"
                excludes="one-jar-boot-0.95.jar"/>
        <fileset refid="runtime.dependency.fileset"/>
    </copy>

    <jar jarfile="${onejardir}/${jarfile}" update="true"
            basedir="${onejardir}" excludes="${jarfile}"/>
</target>

But what of Maven?

Maven

Where Ant asks, How do I make this cake? - Maven asks Where can I find cake ingredients? But Maven does provide a mechanism for adding new recipes, the assembly plugin.

An assembly is a description of packaging for Maven, and is usually hooked into the package phase in your build lifecycle. (The assembly plugin is much simpler than adding new packaging with Plexus, the method described in the link.)

To build a One-JAR with Maven and the assembly plugin, add a new assembly descriptor which follows the outline of building with Ant, taking care to unpack the One-JAR prototype JAR and add to it Main.jar and its dependencies.

This is better explained by example.

Example

The sources

Unfortunately, One-JAR is not in the Maven central repository, so it is included here as part of the project. That is the reason for the added repository in the POM and the lib/ files. Ignoring directories:

  • lib/com/simontuffs/one-jar/0.95/one-jar-0.95.jar
  • lib/com/simontuffs/one-jar/0.95/one-jar-0.95.pom
  • pom.xml
  • src/assembly/one-jar.xml
  • src/main/java/hm/binkley/Main.java
  • src/main/resources/log4j.properties

The POM

<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>hm.binkley</groupId>
    <artifactId>Main</artifactId>
    <packaging>jar</packaging>
    <version>1.0</version>
    <name>One-JAR Example</name>
    <url>http://binkley.blogspot.com/</url>

    <repositories>
        <repository>
            <id>project</id>
            <name>Project Repository</name>
            <url>file:///${basedir}/lib</url>
            <layout>default</layout>
        </repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>hm.binkley.Main</mainClass>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>com.simontuffs.onejar.Boot</mainClass>
                        </manifest>
                    </archive>
                    <descriptors>
                        <descriptor>src/assembly/one-jar.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>attached</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.simontuffs</groupId>
            <artifactId>one-jar</artifactId>
            <version>0.95</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
    </dependencies>
</project>

The assembly

In src/main/assembly/one-jar.xml:

<assembly>
    <id>one-jar</id>
    <formats>
        <format>jar</format>
    </formats>
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <outputDirectory/>
            <unpack>true</unpack>
            <includes>
                <include>com.simontuffs:one-jar</include>
            </includes>
        </dependencySet>
        <dependencySet>
            <outputDirectory>main</outputDirectory>
            <includes>
                <include>${groupId}:${artifactId}</include>
            </includes>
        </dependencySet>
        <dependencySet>
            <outputDirectory>lib</outputDirectory>
            <scope>runtime</scope>
            <excludes>
                <exclude>com.simontuffs:one-jar</exclude>
                <exclude>${groupId}:${artifactId}</exclude>
            </excludes>
        </dependencySet>
    </dependencySets>
</assembly>

The finished One-JAR

  • META-INF/MANIFEST.MF
  • com/simontuffs/onejar/Boot.class
  • com/simontuffs/onejar/Boot.java
  • com/simontuffs/onejar/Handler$1.class
  • com/simontuffs/onejar/Handler.class
  • com/simontuffs/onejar/Handler.java
  • com/simontuffs/onejar/JarClassLoader$ByteCode.class
  • com/simontuffs/onejar/JarClassLoader.class
  • com/simontuffs/onejar/JarClassLoader.java
  • doc/one-jar-license.txt
  • main/Main-1.0.jar
  • lib/log4j-1.2.14.jar

Thursday, December 14, 2006

Brilliant: C to MIPS to Java bytecode

NestedVM is one of the cleverest solutions to the problem of legacy C and C++ code I have ever seen: use GCC to compile to MIPS machine instructions, then translate those directly into Java bytecode.

There is also a good slideshow.

A straight-forward example is a pure-Java translation of the SQLite JDBC driver.

Wednesday, November 22, 2006

What is the type of this in Java?

I was late to read: Peter Ahé has a wonderful post on the type of this.

Among the gems:

  • Design issues with generics
  • A lengthy, well-developed example
  • Laird Nelson is a great name

Thursday, November 02, 2006

Java enum misuse

The Java enum is a nice feature, but like anything it is open to abuse. Witness:

enum OverTheTop {
    A, B;

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(final String value) {
        this.value = value;
    }
}

Even though the instances of OverTheTop are fixed and immutable, enums are after all simply class instances and can be use anyway a class can be used. This is the same problem with unmodifiable collections having modifiable members.

You could view enums as a generalization of singletons, having a fixed number of members not limited to just one. (Class loading is thread safe — does this mean one can use a single-member enum to implement a thread-safe singleton?)

As abusive as enums with setters seems, worse still remains:

enum TrulyUnpredictable {
    A, B;

    private Runnable runnable;

    public void setRunnable(final Runnable runnable) {
        this.runnable = runnable;
    }

    public void run() {
        new Thread(runnable).start();
    }
}

As unmaintainable as this seems (what does TrulyUnpredictable.A.run() do?), there are legitimate uses for complex enums.

Say you have a limited set of algorithm implementations and would like to switch on them:

enum Algorithm {
    FAST(ImplementationFactory.getInstance("FAST")),
    ACCURATE(ImplementationFactory.getInstance("ACCURATE")),
    EFFICIENT(ImplementationFactory.getInstance("EFFICIENT"));

    private final Implementation implementation;

    Algorithm(final Implementation implementation) {
        this.implementation = implementation;
    }

    public double calculate() {
        return implementation.calculate();
    }
}

And for the fan of difficult syntax:

enum Algorithm {
    FAST() {
        public double calculate() {
            new FastImplementation().calculate();
        }
    },
    ACCURATE() {
        public double calculate() {
            new AccurateImplementation().calculate();
        }
    },
    EFFICIENT() {
        public double calculate() {
            new EfficientImplementation().calculate();
        }
    };

    public abstract double calculate();
}

There are very many variations on these themes, but it is not too difficult to reach the point where no one can read your code except you.

Monday, October 30, 2006

The null collection anti-pattern

NEVER do this:

public Collection<T> doTheMacarena() {
    if (isPresidentialElection())
        return null;

    return visitSouthAmerica();
}

ALWAYS throw exceptions or return empty collections; never use null as a kind of "soft exception". Either:

if (isPresidentialElection())
    throw new UnwiseCampaignTacticException();

Or:

if (isPresidentialElection())
    return Collections.emptySet();

Are preferable, depending on whether the return-condition is fast-failure or the "no data" sort.

How would you like to spend your day debugging:

for (final Dancer dander : doTheMacarena())
    dancer.dazzleWithSmoothMoves();

From inside miles of nested code across several transaction and remote boundaries?

UPDATE: A nice post from Nishanth Shastry on the for-each loop. Look at item #6, Return zero length arrays or empty lists rather than nulls.

Monday, October 16, 2006

Live or Memorex?

The Daily WTF has run a series of posts on Virtudyne, a $200 million spectacular failure of a software company.

Many commenters have suggested that the anonymized company referred to throughout is my former employer, SimDesk.

I signed a document upon leaving SimDesk which prevents me from expressing my opinion about such things, but I hope you might enjoy reading the articles nonetheless. And please sweep for bugs, just to be sure.

Sunday, October 01, 2006

Correction for read-only Java objects

The problem

In my own code I sometimes bypass a getter for a final field in favor of direct field access for struct-like classes:

public class BigFoot {
    public final int shoeSize;

    public BigFoot(final int shoeSize) {
        this.shoeSize = shoeSize;
    }
}

I figure: why not? As the field is final there is no need for modifying behavior in a getter method. This seems ideal for data transfer objects (DTOs).

However Miles Barr points out the big flaw with this idea. It is subtle and has to with how the Java compiler deals with direct field access. Miles explains the problem as well as anyone and has a clear example. Fundamentally, you lose polymorphism for shadowed variables and bad things result.

The solution

The mistake for my DTO was not carrying the notion of simple struct-ness to its full conclusion. How much sense does it make to extend DTOs?

public final class BigFoot {
    public final int shoeSize;

    public BigFoot(final int shoeSize) {
        this.shoeSize = shoeSize;
    }
}

If the class is marked final then there will never be a problem with shadowing fields in subclasses.

A caveat

Sometimes I want to extend my DTOs when I have a set of similar data to represent and extract out the common fields in to a base class.

But this is an implementation detail. Logically there is no class relationship among the DTOs and the problem with shadowed fields is one which exposes an implementation detail to the user.

So don't do that.

Wednesday, September 20, 2006

Tom Ball's Hacking javac

Tom Ball posts a chok-full-of-nuts run through of the nifty javac happenings comming out of JDK6, leading to things like Sorcerer.

Normally I avoid posts which simply link to someone else (I rely on Erik's Linkblog for that beneficial service, but he's on vacation right now), but Ball is really on the ball with this one. I can't wait to try these out in a real project.

Wednesday, September 13, 2006

JPMorgan Investment Bank

I've been hired on this week to a permanent position with JPMorgan Investment Bank—no more contracting for me.

It's a double pleasure: I've been picked by a team with former ThoughtWorkers, an all-agile team. After getting some preliminaries out of the way, today I'll dial in for my first daily standup in several years.

I was just reading Tim Ottinger in More Work? discuss some of the benefits of agile development. It's great to see a smart place like JPMorgan with agile teams and a management that believes in its staff.

Wednesday, September 06, 2006

The continuing influence of Smalltalk

My friend Paul Holser likes to point out to me how great Smalltalk is. Just this past weekend he and I were chatting about it at the Rice's opening game (we beat the spread).

Lo and behold, why the lucky stiff mentions on 06 Sep 2006 at 13:17 (emphasis mine):

So, Matz cites four reasons for this decision:

  1. The spread of ActiveSupport has increased the need for strings and symbols to be united as hash keys.
  2. To address RCR 342 , which would allow sorting of symbols. (Try: Symbol.all_symbols.sort.)
  3. Smalltalk’s symbols are a subclass of string. (He adds that this is his most motivating reason to do it.)
  4. Using symbols as immediate values can cause them to venture into pointer territory, particularly on OSX .

Smalltalk never dies, it just slowly gets absorbed by languages with good taste.

Tuesday, September 05, 2006

Java applications, messaging and exceptions

On and off I have looked at messaging for Java applications as an alternative, more loosely coupled design pattern. Particularly for smaller applications messaging has some interesting solutions in lieu of other approaches.

Take the event listener model for AWT/Swing. Each component is responsible for maintaining its own listener event list, and each listener is responsible for finding the component it wants to get events from. This is, of course, the Observer pattern.

I want more decoupling. Message busses decouple this pattern by managing listeners and delivering events—I grew up calling this publish/subscribe—mixing in the Mediator pattern models the bus.

Channels and Subscribers

I'm going to call the bus a channel. There are many common vocabulary choices for the kind of simple message bus I have in mind, and channel is the one I used most with Gregory Hohpe who introduced me to this design. Start with the channel interface:

public interface Channel {
    void subscribe(Object subscriber);
    void unsubscribe(Object subscriber);
    void publish(Object message) throws Exception;
}

Choices, choices. Most messaging interfaces I see use a topic text to distinguish messages when publishing. But like the AWT/Swing event system, I prefer objects so that I may use inheritance to narrow or widen the scope of events I receive. Subscribers receive any intersection or union of message types they want using simple method overloading. For example:

interface BobTheBuilder {
    void onMessage(CanHeFixItRequest message);
    void onMessage(YesHeCanDispute message);
}

class MessageLogger {
    public void onMessage(Object message) {
        SomeLogger.logMessage(message);
    }
}

MessageLogger subscribes to all possible message types planning to ambitiously log everything. BobTheBuilder is only interested in requests to fix something or in criticisms of his abilities.

Supporting the union of disjoint message types explains why subscribe(Object):void and unsubscribe(Object):void take object arguments rather than using a Subscriber interface. Sketch out what Subscriber might look like with typed messages:

interface Subscriber<T> {
    void onMessage(T message);
}

This works great is a subscriber wants a single type of message, but Java does not support classes implementing the same interface multiple times—generics does not produce different interfaces:

interface IllegalJavaSubscriber {
        implements Subscriber<String>, Subscriber<Integer> {
    // Will not compile.
}

And the lack of typed interfaces for subscribers implies that the signature for onMessage(Object):void cannot narrow either. What to do? The only option is reflection. So I reflect for "onMessage" methods with the correct signature and handle overriding and overloading in the bus.

All in all I get a lot of flexibility for very little work by subscribers using the bus.

Exceptions

But what of exceptions? I realized, given the inheritance of message types, that I could simply publish exceptions as messages, same as any other type. Exception handlers simply subscribe to messages:

class ExceptionLogger {
    public void onMessage(final Exception e) {
        SomeLogger.logException(e);
    }
}

This is akin to how AOP works but without the extra syntax or new language to learn. The try/catch normally in each subscriber for logging exceptions is gathered together into the message bus with pseudo-code akin to:

for (final Subscriber subscriber
        : getSubscribersForMessage(message))
    try {
        invokeOnMessage(subscriber, message);
    } catch (final Exception e) {
        this.publish(e); // I am a channel
    }

This simplicity is very appealing, but it leaves out an interesting possibility: that subscribers could try redeliving a message to just the failed cases. Adding one more reflected method adds this option:

class SystemMonitor {
    public void onMessageException(Exception e,
        Object subscriber, Object message) {
        fixSystem(); // magic
        retryMessage(subscriber, message); // more magic
    }
}

In principal a subscriber could republish using the signature after fixing some broken part of the system. It would also make logging more informative.

Active Messages

Using pure reflection opens up another design choice, active messages. Simply having messages themselves provide an onMessage method and subscribe to the channel. Messages can publish themselves. As clever as this seems, it does leave me in fear of maintaining someone else's system years hence in which the entire thing is a ball of spaghetti with messages and subscribers calling hither, thither and yon.

Debugging is a problem with systems like this. YMMV.

Code

Some simple code illustrating this post.

Tuesday, August 29, 2006

Filling in the Java closure gap

The interesting FuntionalJ library fills in a gap with reflective function objects while waiting for JDK7 closures. With flavors of C++ functors and Python zip and tuples, FuntionalJ is a gem.

Tuesday, August 22, 2006

Two new toys to try out

Today I'm looking at two new web toys:

Getting started on JRuby, a great post

Ola Bini has a great post on getting started with JRuby on Windows, The JRuby Tutorial #1: Getting started, followed up with more excellent posts in the JRuby tutorial series.

Monday, August 21, 2006

Mapping a Java bean

This is a straight-forward code post.

public class BeanMap<T>
        extends AbstractMap<String, Object> {
    private final T bean;
    private final Set<PropertyDescriptor> descriptors;

    public BeanMap(final T bean)
            throws IntrospectionException {
        this.bean = asNotNull(bean, "Missing bean");

        final Set<PropertyDescriptor> descriptors
                = new HashSet<PropertyDescriptor>();

        for (final PropertyDescriptor descriptor
                : getBeanInfo(bean.getClass()).getPropertyDescriptors())
            // Only support simple setter/getters.
            if (!(descriptor instanceof IndexedPropertyDescriptor))
                descriptors.add(descriptor);

        this.descriptors = unmodifiableSet(descriptors);
    }

    public Set<Entry<String, Object>> entrySet() {
        return new BeanSet();
    }

    @Override
    public Object get(final Object key) {
        return super.get(checkKey(key));
    }

    @Override
    public Object put(final String key, final Object value) {
        checkKey(key);

        for (final Entry<String, Object> entry : entrySet())
            if (entry.getKey().equals(key))
                return entry.setValue(value);

        return null;
    }

    @Override
    public Object remove(final Object key) {
        return super.remove(checkKey(key));
    }

    private String checkKey(final Object key) {
        // NB - the cast forces CCE if key is the wrong type.
        final String name = (String) key;

        if (!containsKey(asNotNull(name, "Missing key")))
            throw new IllegalArgumentException("Bad key: " + key);

        return name;
    }

    private class BeanSet
            extends AbstractSet<Entry<String, Object>> {
        public Iterator<Entry<String, Object>> iterator() {
            return new BeanIterator(descriptors.iterator());
        }

        public int size() {
            return descriptors.size();
        }
    }

    private class BeanIterator
            implements Iterator<Entry<String, Object>> {
        private final Iterator<PropertyDescriptor> it;

        public BeanIterator(final Iterator<PropertyDescriptor> it) {
            this.it = it;
        }

        public boolean hasNext() {
            return it.hasNext();
        }

        public Entry<String, Object> next() {
            return new BeanEntry(it.next());
        }

        public void remove() {
            it.remove();
        }
    }

    private class BeanEntry
            implements Entry<String, Object> {
        private final PropertyDescriptor descriptor;

        public BeanEntry(final PropertyDescriptor descriptor) {
            this.descriptor = descriptor;
        }

        public String getKey() {
            return descriptor.getName();
        }

        public Object getValue() {
            return unwrap(new Wrapped() {
                public Object run()
                        throws IllegalAccessException,
                        InvocationTargetException {
                    final Method method = descriptor.getReadMethod();
                    // A write-only bean.
                    if (null == method)
                        throw new UnsupportedOperationException(
                                "No getter: " + descriptor.getName());

                    return method.invoke(bean);
                }
            });
        }

        public Object setValue(final Object value) {
            return unwrap(new Wrapped() {
                public Object run()
                        throws IllegalAccessException,
                        InvocationTargetException {
                    final Method method = descriptor.getWriteMethod();
                    // A read-only bean.
                    if (null == method)
                        throw new UnsupportedOperationException(
                                "No setter: " + descriptor.getName());

                    final Object old = getValue();
                    method.invoke(bean, value);
                    return old;
                }
            });
        }
    }

    private static interface Wrapped {
        Object run()
                throws IllegalAccessException,
                InvocationTargetException;
    }

    private static Object unwrap(final Wrapped wrapped) {
        try {
            return wrapped.run();

        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);

        } catch (final InvocationTargetException e) {
            // Javadocs for setValue indicate cast is ok.
            throw(RuntimeException) e.getCause();
        }
    }
}

The idea is simple: give the Java getter/setter idiom a Map interface. Commons Beanutils already does this but with a significant difference.

My example class is very brittle. It doesn't like null, wrong classes or missing keys. And in a brittle language like Java, this is a good thing. This kind of brittleness finds bugs quickly following the venerable fail-fast principle.

Avoid code which returns null or silently converts wrong-class arguments. You pay now in return for a clear conscience in the long term. I have better things to do with my time than debug NullPointerExceptions.

Thursday, August 17, 2006

Class literal woes

In Bitten by the class literal change in Tiger Michael Nascimento writes about the surprising impact of JDK5 changing the rules for Foo.class. As simple as that.

Amazing how such a small change can have ramifications. This is food for thought when making a "small change" as I often do while cleaning old code: How can it make a difference? should be asked as a real question, not as gesture to shrug off the nay-sayers.

May I follow my own advice!

Tuesday, August 15, 2006

Strange mini anti-pattern

It's strange seeing this:

List copy = (List) ((ArrayList) original).clone();

When this will do:

List copy = new ArrayList(original);

And as a bonus original need not be an ArrayList.

Saturday, August 12, 2006

Ask, and ye shall receive

No sooner had I posted a Java enhanced for loop wish than a commenter pointed out the JGA and jga & the java 1.5 forloop. Shades of my beloved STL!

The JGA would be another excellent addition to the JDK and an encouragement to a well-proven style of programming common in many programming languages.

Friday, August 11, 2006

Read-only enhanced for loops in Java

I was just commenting on Paul Holser's blog about this small idiom using the Java enhanced for loop:

for (final T t : unmodifiable(collection)) {
    doSomethingWith(t);
}

The plumbing is simple:

public static <T> Iterable<T> unmodifiable(
        final Collection<T> c) {
    return new Iterable<T>() {
        public Iterator<T> iterator() {
            // Presuming a static decorator method
            // akin to Collections.unmodifiableCollection()
            return unmodifiableIterator(c.iterator());
        }
    };
}

Naturally, I wish Sun would add something like this to java.util.Collections, but I am sure they get many, many requests for JDK additions. Adding in a cleaned up Jakarta Collections library would help.

Another example of this sort of thing is a filterable iterator:

for (final T t : filter(collection, filter) {
    // Only works on collection elements
    // accepted by the filter.
    doSomethingWith(t);
}

Anyway, Paul has a lot of interesting ideas in store for Jaggregate 3.0.

UPDATE: An anonymous commenter made the observation that an immutable Iterable is useless in an enhanced for loop. D'oh! I should not have overlooked that point when I used the enhanced for loop in my examples. However, the read-only property is still useful when you call iterator().

Thursday, August 10, 2006

Replace simulated Java lists with Iterable

While cleaning old Java code I ran across this pre-Tiger pattern several times:

class Thingies {
    private final List things = new ArrayList();

    // Other useful fields

    public List getThings() {
        return Collections.unmodifiableList(things);
    }

    public void addThing(final Thing thing) {
        things.add(thing);
    }

    // Other useful methods
}

Essentially the author intended to simulate a sort of List decorated with other, useful information for a business object. Hiding the list internally is a Good Thing and helps abstraction. Using unmodifiableList is great.

But with Tiger and generics, I can do better:

class Thingies implements Iterable<Thing> {
    private final List things = new ArrayList();

    // Other useful fields

    public Iterator<Thing> iterator() {
        return things.iterator();
    }

    public void addThing(final Thing thing) {
        things.add(thing);
    }

    // Other useful methods
}

Now I can use the class with Tiger foreach syntax:

for (final Thing thing : instanceOfThingies) {
    // Do something with thing.
}

This advice is available in many places on the Internet, and is good advice. But did you notice something wrong with the example? What happens with thingies.iterator().remove()? I introduced an abstraction leak.

Let's fix the leak:

public Iterable<Thing> iterator() {
    return new Iterator<Thing>() {
        final Iterator<Thing> it = things.iterator();

        public boolean hasNext() {
            return it.hasNext();
        }

        public Thing next() {
            return it.next();
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
}

Now if the caller decides to use thingies.iterator() directly, they still cannot modify the underlying list.

A neat trick

Continuing this theme, I also ran across a neat trick. The old code has a small class hierarchy which the simulated list managed. Typical usage:

class FourWheeler {
}

class Sedan extends FourWheeler {
}

class Pickup extends FourWheeler {
}

// In another class far, far away:
final Iterator sedans = fourWheelers.getList().iterator();
while (sedans.hasNext()) {
    final Sedan sedan = (Sedan) it.next();
}

// In yet another class even more far, far away:
final Iterator pickups = fourWheelers.getList().iterator();
while (pickups.hasNext()) {
    final Pickups pickup = (Pickup) it.next();
}

The thing is, the four wheelers list manager only held one type of four wheeler at a time so the caller was safe in casting as long as they were careful in updating the list. But this is very wordy. One approach is to generify the list manager:

class FourWheelers<T extends FourWheeler> {
    private final List<T> list = new ArrayList<T>();

    // Rest of class uses T instead of FourWheeler.
}

This is a great approach to the problem for new code. But there is a smaller change one can make to the class that also works. Add a new method:

public Iterable<Sedan> sedans() {
    return new Iterable<Sedan>() {
        public Iterator<Sedan> iterator() {
            final Iterator it = list.iterator();

            public boolean hasNext() {
                return it.hasNext();
            }

            @SuppressWarnings({"unchecked"})
            public Sedan next() {
                return (Sedan) it.next();
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }
        }
    };
}

And likewise for Pickup. You can abstract this common pattern to a base class and simplify the methods further:

public Iterable<Sedan> sedans() {
    return new FourWheelerIterable<Sedan>(list.iterator());
}

Usage is now like this with all the nasty casting hidden away:

// Back in a far, far away class.
for (final Sedan sedan : fourWheelers.sedans()) {
    // Do something with sedan.
}

UPDATE: Jörg has a great observation in the comments: you may need more than one kind of generic Iterable<T> for a complex class.

Wednesday, August 09, 2006

Crossing generics and covariant returns

Quick: why doesn't this compile?

fred.setFoo(new Foo());

Ok, some context:

class Bob<Foo extends Foo> {
    private Foo foo;

    public void setFoo(final Foo foo) {
        this.foo = foo;
    }
}

class Fred extends Bob<Bar> {
}

See it now? How about now:

class Foo {
}

class Bar extends Foo {
}

class Bob<NOTFOO extends Foo> {
    private NOTFOO foo;

    public void setFoo(final NOTFOO foo) {
        this.foo = foo;
    }
}

class Fred extends Bob<Bar> {
}

Yes, it was a mean trick to name a generic parameter the same as the class it extends. Sensibly, SUN's javac complains "illegal forward reference". I had to reread several times the code this example came from before it finally clicked what had happened.

But enough; on to the meat of the post.

I was cleaning some code and noticed this mini-anti-pattern in many places:

class Bob {
    private Foo foo;

    public Foo getFoo() {
        return foo;
    }

    public void setFoo(final Foo foo) {
        this.foo = foo;
    }
}

class Fred extends Bob {
}

class SomewhereElse {
    public void doWork(final Fred fred) {
        final Bar bar = (Bar) fred.getFoo();
    }
}

This style is quite commmon in pre-generics Java where there are parallel inheritance hierarchies: Foo goes with Bob, Bar goes with Fred, et al, and all the common code is pushed down into the lowest base class. All that casting makes my eyes sore.

But using generics, I get the advantages of covariant returns without needing any extra coding:

class Bob<F extends Foo> {
    private F foo;

    public F getFoo() {
        return foo;
    }

    public void setFoo(final F foo) {
        this.foo = foo;
    }
}

class Fred extends Bob<Bar> {
}

Now the syntax error I first posed is a real time-saver: instead of getting a ClassCastException at runtime, I get a compile error when trying:

fred.setFoo(new Foo());

The correct call is now:

fred.setFoo(new Bar());

What are covariant returns? To get generic code like this to work right, Java picked up covariant returns for free:

class abstract NumberPicker {
    public abstract Number pickANumber();
}

class IntegerPicker extends Base {
    public Integer pickANumber() {
        return 42;
    }
}

Because an Integer is a Number, Java recognizes that declaring IntegerPicker to return an Integer for pickANumber() satisfies the contract for NumberPicker: covariant returns. Generics uses the same trick in the compile when narrowing the return type for getFoo() in the first examples, or something near enough.

You can read more on this and other goodies in Angelika Langer's Java Generics FAQs.

Tuesday, August 08, 2006

SQL and XML and JDBC4 and you

I missed it when he first posted: Lance Anderson (lead for JDBC4) has an excellent post with short recipes on using XML and SQL with JDBC4, JDBC 4.0 SQLXML Interface. Just the sort of thing when one is poking around for an easy way to use the new XML features of JDBC4.

Friday, August 04, 2006

A refinement on constructor tidiness

Last year I wrote a post about using generics to improve constructor argument checking, Let generics make your Java constructor cleaner. Since then I have refined the example method, asNotNull.

The original:

public static <T> T asNotNull(final T input) {
    if (input == null)
        throw new NullPointerException();

    return parameter;
}

And updated:

public static <T> T asNotNull(
        final T input, final String message) {
    if (null == input)
        throw new IllegalArgumentException(message);

    return input;
}

There are two differences:

  1. I throw IllegalArgumentException instead of NullPointerException. In addition to this being arguably more correct for the semantics of those two exceptions, it is also more useful as I will know that any NullPointerException is because of a call on a null object.
  2. I use a message for the thrown exception—usually of the form "Missing variableName"—to aid in fixing the problem from the stack trace output.

Another reason for the changes are consistency. I make use of other "contract"-based methods such as asNotEmpty, etc., who all throw IllegalArgumentException with an explanatory message. The consistency makes it easier for other programmers to take up the methods into their own code.

Thursday, August 03, 2006

svnmerge

I wish I had known about svnmerge ages ago. Happily Ken Kinder explains simple use in a good article, Subversion merge tracking with svnmerge.

Wednesday, August 02, 2006

Doug Lea's list of Mustang concurrency changes

Doug Lea of java.util.concurrent fame maintains the Concurrency JSR-166 Interest Site. One of the interesting links is to Sun bug activity related to JSR166, Concurrency or Collections.

Lea's bug list is very handy for watching for interesting Mustang changes in concurrency or collections as they happen. I only stumbled across the list today—thank Google—, and noticed the nifty Add @see newSetFromMap for Map implementations without Set implementations fix, which got me to look at java.util.Collections again and check the new methods.

Serendipity strikes.

Javadoc generic type parameters

While looking at the new NavigableSet interface introduced into JDK 6 (Mustang), I noticed this in the class javadocs:

 * @param <E> the type of elements maintained by this set
 * @since 1.6
 */
public interface NavigableSet<E> extends SortedSet<E> {

Well, that is new. I've not seen a generic type parameter used with the @param tag before.

Looking at the documentation for Javadoc 1.5, apparently this feature has been around since generics started.

A quick comparison between the sources of java.util.Set for JDK 5 and JDK 6 shows that Sun has added @param tags to the generic collection classes in Mustang.

Unfortunately, IntelliJ IDEA 6.0 beta does not show these class generic tags in the class quickdocs, which is why I never noticed them before. Hopefully JetBrains fixes this at some point.

On the flip side, the JDK 6 javadoc tool does handle the tags. Witness java.util.Set for Mustang.

Tuesday, August 01, 2006

Java generics trick to work out parameter types

Another nifty trick I hadn't seen before which I ran across on the Hibernate page for their generic DAO classes:

public abstract class GenericHibernateDAO<T, ID extends Serializable>
        implements GenericDAO<T, ID> {
    private Class<T> persistentClass;
    private Session session;

    public GenericHibernateDAO() {
        this.persistentClass = (Class<T>)
                ((ParameterizedType) getClass()
                .getGenericSuperclass())
                .getActualTypeArguments()[0];
    }

    // ...
}

Playing around with this revealed two things to me:

  1. This trick only works for concrete subclasses.
  2. The concrete subclass needs to not be generic, at least for the parameter in the interesting expression above.

So one could, for example, create a generic factory using this technique, although there does not seem on the surface to be much advantage:

public abstract class FactoryBase<T> {
    private final Class<T> type = (Class)
            ((ParameterizedType) getClass()
            .getGenericSuperclass())
            .getActualTypeArguments()[0];

    protected FactoryBase() { }

    public Class<T> getType() { return type; }

    public T create()
            throws IllegalAccessException, InstantiationException {
        // Real implementations do something more interesting
        // than imitate "new T()".
        return type.newInstance();
    }
}

public class FredFactory
        extends FactoryBase<Fred> { }

public class Main {
    public static void main(final String arguments) {
        final Fred fred = new FredFactory().create();
    }
}

How different is this from supplying a Class literal to the factory consturctor?

getGenericSuperclass() seems one of those "back pocket" techniques: something I'll keep handy if the need arises but which I don't go out of my way to use.

UPDATE: A little playing shows that the minimal requirement is that the generic parameter whose index is queried with getActualTypeArguments() must be concrete; it is ok for another parameter to be a generic:

public class Bob<T, U> {
    final Class<T> tClass
            = getGenericTypeByIndex(getClass(), 0);

    private static Class getGenericTypeByIndex(
            final Class clazz, final int index) {
        return (Class) ((ParameterizedType) clazz
                .getGenericSuperClass())
                .getActualTypeArguments()[index];
    }
}
}

This snippet works ok as:

public class Fred<U> extends Bob<Fred, U> {
    public static void main(final String arguments) {
        new Fred<String>();
    }
}

But fails at runtime with a ClassCastException trying to turn a sun.reflect.generics.reflectiveObjects.TypeVariableImpl into a java.lang.Class:

public class Sally<T, U> extends Bob<T, U> {
    public static void main(final String arguments) {
        new Sally<Sally, String>();
    }
}

Monday, July 31, 2006

Peter Norvig's Infrequently Answered Questions

Here's a Java resource I wish I had known about long ago: Peter Norvig's Java IAQ.

UPDATE: Thanks to anonymous for pointing out I mispasted in the link!

Saturday, July 29, 2006

A Java trick with varargs to enforce argument count

Perhaps you've seen this before, but it is new to me:

public void doSomethingAmazing(
        final String firstArgument,
        final String... restOfArguments) {
    // Do something amazing with the arguments
}

What is the point of firstOne and restOfThem (besides looking a little LISPy)?

Fortunately, the coder had this comment for the method: Change from checking at runtime for one or more arguments to syntatically enforcing a mandatory first argument and optional list of remaining arguments. A quick check showed the previous version as:

public void doSomethingAmazing(
        final String... arguments) {
    // Do something amazing with the arguments
}

Aha, how clever! Whereas before the call:

doSomethingAmazing();

compiled but at runtime threw an IllegalArgumentException for empty arguments[], now the same call is a syntax error caught by the compiler. The correct new call is:

doSomethingAmazing("wonderful");

I like it.

UPDATE: Paul Holser points out to me that he uses this trick in the excellent JAggregate. As I reviewed that code within the past several months, I now realize that it is most likely I had already seen this trick there first. Paul is a clever guy, and deserves the credit.

Wednesday, July 19, 2006

The double inheritance pattern in Java

Java is a single inheritance language, yes? Generics adds a new wrinkle to that, however. Consider this problem:

You have a class hierarchy you wish to wrap. For instance, you want wrapped versions of JTextComponent and its subclasses which implement additional functionality or default behaviors. So the first wrapping looks like this:

public class MyTextComponent
        extends JTextComponent {
    // ...
}

The second wrapping looks like this:

public class MyTextField
        extends JTextField or MyTextComponent {
    // ...
}

Oops! What should the second wrapper extend?

Generics provides a neat, if wordy, solution for this problem. Have the wrapper hierarchy extend only within itself, and have generic types extend the wrapped hierarchy. The wrapper hierarchy delegates to the wrapped one. Thus:

public class LabeledTextComponent<F extends JTextComponent>
        extends Box { // Box is just illustrative
    protected final F field;

    private final JLabel label;

    protected LabeledTextComponent(final F field,
            final String labelText) {
        super(BoxLayout.LINE_AXIS);

        this.field = field;
        label = new JLabel(labelText, SwingConstants.TRAILING);

        label.setLabelFor(field);
        
        add(label);
        add(field);
    }

    // ... public constructors

    // delegates via field specific to JTextComponent

    public String getText() {
        return field.getText();
    }

    public void getText(final String text) {
        field.setText(text);
    }

    // ... other delegates

    // methods specific to LabeledTextComponent

    public JLabel getLabel() {
        return label;
    }
}

public class LabeledTextField<F extends JTextField>
        extends LabeledTextComponent<F> {
    protected LabeledTextField(final F field,
            final String labelText) {
        super(field, labelText);
    }

    public LabeledTextField(final String labelText) {
        super(new JTextField(), labelText);
    }

    public LabeledTextField(final int columns,
            final String labelText) {
        super(new JTextField(columns), labelText);
    }

    // ... other public constructors, etc.
}

And a further example:

public class LabeledPasswordField<F extends JPasswordField>
        extends LabeledTextField<F> {
    protected LabeledTextField(final F field,
            final String labelText) {
        super(field, labelText);
    }

    // ... public constructors

    // delegates via field specific to JPasswordField

    public char[] getPassword() {
        return field.getPassword();
    }

    public void getPassword(final char[] password) {
        field.setPassword(password);
    }

    // ... other delegates
}

Generics combined with delegates simulates a kind of multiple inheritance similar to mixins. One can extend the idea one step further:

public interface Required {
    /** Checks if the field requires text to be valid. */
    boolean isRequired();

    /** Toggles that the field requires text to be valid. */
    void setRequired(final boolean required);

    /** Checks if the field is required and if the text is missing. */
    boolean isMissing();
}

public class RequiredTextField extends JTextField
        implements Required {
    private boolean required;

    // Required
    public boolean isRequired() {
        return required;
    }

    public void setRequired(final boolean required) {
        this.required = required;
    }

    public boolean isMissing() {
        return required
                && null != getText();
                && getText().length() > 0;
    }
}

public class RequiredLabeledTextField
        <F extends JTextField & Required>
        extends LabeledTextField<F>
        implements Required {
    protected RequiredLabeledTextField(final F field,
            final String labelText) {
        super(field, labelText);
    }

    // Required
    public boolean isRequired() {
        return field.isRequired();
    }

    public void setRequired(final boolean required) {
        field.setRequired(required);
    }

    public boolean isMissing() {
        return field.isMissing();
    }
}

Now it is simple to glue it all together cleanly, maintaining separation of concerns and working through interfaces based on capabilities rather than concrete classes.

Generics to the rescue!

NB — I relied heavily on my background in C++ templates for conceptualizing this pattern. But I believe it likely I am treading no new ground. If you know an earlier or better reference for this pattern, please drop me a line. I want to give credit to where it is due.

Friday, June 23, 2006

Skipping read-only text components in Swing with TAB

After a superficial web search, I did not turn up a simple way (read cut and paste) to TAB over read-only components while navigating a container in Swing. JComboBox, JTextComponent and JTree all have an isEditable/setEditable(boolean) pair, however it has different meaning for each of them.

The case I am interested in JTextComponent. For text components, uneditable is equivalent to read-only: you can select the text from the component but cannot change it. The alternative is to disable the component, but then the text is not selectable for copying.

So, given a uneditable text component, what happens when I traverse through a form with the TAB key? Unfortunately, the JDK by default will move the focus (the caret) into the read-only text field even though you cannot type anything. Fixing the form to skip over read-only text fields is straight-forward but not directly documented:

public static void skipReadOnlyTextComponents(
        final Container container) {
    // Without this, JDK ignores policy
    container.setFocusCycleRoot(true);
    container.setFocusTraversalPolicy(new MyPolicy());
}

class MyPolicy extends LayoutFocusTraversalPolicy {
    @Override
    protected boolean accept(final Component c) {
        return !isReadOnly(c) && super.accept(c);
    }

    private static boolean isReadOnly(
            final Component c) {
        if (c instanceof JTextComponent)
            return !((JTextComponent) c).isEditable();

        return false;
    }
}

In broader use, it is worthwhile to make an Editable interface for isEditable/setEditable and add that to the instanceof tests in isReadOnly.

Wednesday, June 21, 2006

Answer: Using JFormattedTextField for integers

I wrote earlier about using JFormattedTextField for integers and the difference between using an initial value of Integer (rounds input) v. BigInteger (rejects invalid input). I also wrote that I did not understand why there was a difference.

I now know what happened.

The culprit for handling Integer turns out to be NumberFormat and friends. The rounding behavior is not numerical rounding at all; it is truncating the input text.

The parser for the input stops after finding valid input and returns a parsed value in stringToValue(String):Object. This discards any trailing text, which in the case of parsing an integer is everything from the decimal point forward. The same behavior can be seen with a date parser: Jun 21, 2006xxx parses to Jun 21, 2006 and the xxx is discarded.

The solution to enforce correct input even with trailing garbage is cumbersome: initialize JFormattedTextField with a custom formatter and check that parsed input deparses back cleanly:

new JFormattedTextField(new Integer(0))

becomes:

new JFormattedTextField(new NumberFormatter(
        NumberFormat.getIntegerInstance()) {
    @Override
    public Object stringToValue(final String text)
            throws ParseException {
        // Throws if the input is corrupt from the start
        final Object parsed = super.stringToValue(text);
        final String deparsed = valueToString(parsed);

        // Throws if there is no clean roundtrip,
        // such as trailing garbage characters
        // For date parsing, etc., consider equalsIgnoreCase
        if (!deparsed.equals(text))
            throw new ParseException(text, deparsed.length());

        return parsed;
    }
}) {
    {
        // Initialize to the original starting value
        setValue(new Integer(0));
    }
}

(Yes, the anonymous instance syntax is awkward here.)

That's a lot of work to achieve what seems like a simple goal: actually valid input for a JFormattedTextField.

UPDATE: Given the hoops to jump through for this more "correct" solution, I think I'll stick to new JFormattedTextField(new BigInteger(0)) for now, although that does nothing to help with other input types such as dates.

Tuesday, June 20, 2006

Using JFormattedTextField for integers

I discovered the hard way that:

new JFormattedTextField(new Integer(0))

does not do what I wanted.

What I wanted was to have a text entry field restricted to integers. What I got was a field which rounded off numbers to integers. This was surprising.

After a while of poking at it, I tried using various incarnations of NumberFormat and DecimalFormat in the field constructor with no luck. Perusing the sources was not particularly illuminating either, at least at first.

Finally I noticed that JFormattedTextField.getDefaultFormatterFactory(Object) contained this legerdemain:

if (type instanceof DateFormat) { ... }
if (type instanceof NumberFormat) { ... }
if (type instanceof Format) { ... }
if (type instanceof Date) { ... }
if (type instanceof Number) { /* mucking around with formatter factory */ }

Hmmm. So in a flash of inspiration I tried:

new JFormattedTextField(new BigInteger(0))
and it worked, although I do not entirely understand why. JFormattedTextField maintains separately value, formatter and formatter factory in addition to the document model for text entry and a lot of state options for handling valid and invalid input.

I'm sure its a tour de force for someone at Sun, and most importantly the class works, but quirks like this one are difficult to find and explain.

UPDATE: A colleague of mine asked for more details on this point. To clarify:

Argument Input Behavior
new Integer(0) 3.0 3
3.3 3
new BigInteger(0) 3.0 3
3.3 invalid

So to get non-integral input to be treated as invalid, you must initialize JFormattedTextField with a BigInteger; initializing with an Integer gets a rounding mode instead.

Monday, June 19, 2006

Programmatically show a tool tip in Swing

A better way to do this exists, I am sure, but I failed to find it easily with Google: How to display a tool tip programmatically in Swing:

ToolTipManager.sharedInstance().mouseMoved(
        new MouseEvent(targetComponent, 0, 0, 0,
                0, 0, // X-Y of the mouse for the tool tip
                0, false));

Note the commented line. This is the relative location of the synthetic mouse event to the target component. The (0, 0) example above is as if the user had paused the mouse at the upper-left corner of the component, and the tool tip displays accordingly.

Another choice might be (targetComponent.getWidth(), targetComponent.getHeight()) for the lower-right corner, etc.

I wish Swing had a more straight-forward way of using the tool tip framework programmatically. I would like to be able to reuse tool tips for form validation. But at least this works.

UPDATE: 4 years on and I still get more positive comments on this post than any other. Hopefully the JDK improves in this area.

Monday, June 12, 2006

ViM 7

In another salvo in the endless vi v. Emacs war, the ViM folks released ViM 7.0.

The announcement is about a month old. Why the delay for me mentioning it? Cygwin just updated their 6.4 to 7.0 over the weekend. Too bad the update removed vi from /usr/bin. Oops.

UPDATE: I found one source of my Cygwin trouble. For whatever reason, the ViM 7.0 installation put vim.exe and friends into C:\cygwin\usr\bin instead of /usr/bin. As my default Cygwin installation mounts C:\cygwin\bin as /usr/bin, that means the mount hides the files in the underlying Windows directory:

C:\cygwin\bin -> /usr/bin
C:\cygwin\usr\bin -> hidden underneath

A quick unmount, switch to CMD.EXE, files moved to the right Windows directory, and remount: I can now run vim.

One remaining problem: whither the vi command?

UPDATE: Run the Cygwin installer/updater one more time. There is a patch up for the new ViM 7 package which fixes the missing /usr/bin/vi problem and the overall install issues.

Friday, June 09, 2006

Google Browser Sync

Well, this looks interesting.

Finding a field in Java

A large motivation for me starting this blog was to help me remember useful snippets of code. This is a good example:

Field getField(Class clazz, final String fieldName)
        throws NoSuchFieldException {
    for (; null != clazz; clazz = clazz.getSuperclass()) {
        try {
            final Field field = clazz.getDeclaredField(fieldName);
            field.setAccessible(true);
            return field;
        } catch (final NoSuchFieldException e) { }
    }

    throw new NoSuchFieldException(fieldName);
}

Very simple code, no? But a fact I seem to sometime forget is that inherited fields do not show up in reflection; one must reflect down into the appropriate superclass where the field was declared. The simple method handles the details easily enough.

Thursday, June 08, 2006

Against agilism

As much as I am a fan of agile development methodologies, I must admit that Cedric Beust has some good points against agile.

I need more time to think his post through. It is meaty, lengthy and well-written. It is also a bit abrasive, but I enjoy that style.

Wednesday, June 07, 2006

IntelliJ IDEA build 5321

After several builds that gave me a lot of trouble, IntelliJ IDEA build 5321 seems to hit the spot.

With several of the previous EAP builds the IDE leaked memory fairly badly and I often hit mysterious lock ups for minutes at a time. The only solution was restarting. Worse was that many times the dialog to mail exception reports to JetBrains itself would fail.

Build 5321 does not seem to have these flaws, happily, and seems robust enough for daily use.

Monday, May 22, 2006

Learning more about web continuations

Web continuations fascinate me, but alas I have no current project in which to work on them. So I try to keep up in my reading instead.

I ran across this lengthy post on the "abandoned session" problem by Blushish Coder, one of my favorite code bloggers. Meanwhile, I bide my time looking for the right project for proposing continuations.

Friday, May 19, 2006

Leo Simons on unit tests for complex software

Leo Simons has a useful post on how to organize unit tests for complex software. Included is a nifty chart which explains his post well. I feel chart envy setting in.

Tuesday, May 02, 2006

A debugging glass pane

I've started on a largish Java project (4000+ classes) with a complex Swing UI front-end and have had difficulty working out just which class is in play for a given visual component.

Glass pane to the rescue.

To help me out, I've written a small debugging glass pane based on a universal right-click handler found on Google similar to the example provided in the Swing documentation.

Use is simple:

JFrame frame = ...;
DebugGlassPane.setDebugGlassPaneOn(frame);

Now when you hover the mouse over a component in the content pane, up pops a tooltip identifying the class and instance name. If you want to change the displayed information, edit createTipText(Component).

The complete class:

public class DebugGlassPane
        extends JComponent
        implements MouseListener, MouseMotionListener {
    private final JLayeredPane layered;

    public static void setDebugGlassPaneOn(final JFrame frame) {
        final Component glass = new DebugGlassPane(frame);
        // Must be in this order
        frame.setGlassPane(glass);
        glass.setVisible(true);
    }

    public DebugGlassPane(final JFrame frame) {
        layered = frame.getLayeredPane();

        addMouseListener(this);
        addMouseMotionListener(this);
    }

    public void mouseMoved(final MouseEvent e) {
        setToolTipText(createTipText(getChildUnderMouse(e)));

        redispatchMouseEvent(e);
    }

    public void mouseDragged(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    public void mouseClicked(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    public void mouseEntered(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    public void mouseExited(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    public void mousePressed(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    public void mouseReleased(final MouseEvent e) {
        redispatchMouseEvent(e);
    }

    private String createTipText(final Component c) {
        return "<html>Class: <b>" + c.getClass().getName()
                + "</b><br>Name: <i>" + c.getName();
    }

    private void redispatchMouseEvent(final MouseEvent e) {
        final Component component = getChildUnderMouse(e);

        // E.g., popup menus
        if (component == null) return;

        // redispatch the event
        component.dispatchEvent(
                SwingUtilities.convertMouseEvent(this, e, component));
    }

    private Component getChildUnderMouse(final MouseEvent e) {
        // get the mouse click point relative to the content pane
        final Point containerPoint = SwingUtilities.convertPoint(this,
                e.getPoint(), layered);

        return SwingUtilities.getDeepestComponentAt(layered,
                containerPoint.x, containerPoint.y);
    }
}

Surprisingly, I had a difficult time finding such a class already coded up somewhere. It is quite handy for exploring the UI.

UPDATE: An important fix (already incorporated in the code, above). Say you have a menu bar. The current code throws a NullPointerException. The problem is that all the work is relative to the content pane, but a JFrame can have visual space which recieves mouse events but is not part of the content.

The fix is simple: change getChildUnderMouse(MouseEvent) to work with the component from frame.getLayeredPane() instead of frame.getContentPane(). Sun has a good explanatory diagram and description making this point clear.

Sunday, April 23, 2006

Nifty JDBC 4.0

Today I've been playing with some of the new JDBC 4.0 features in the latest JDK6 beta. In particular, I've been scouting around for a lighter-weight alternative to Hibernate when working with small-sized projects, and one that uses annotations rather than XML.

A few weeks ago I tried out Ammentos, and although in the right direction it did not quite handle everything I threw at it. JDBC 4.0, however, seems just the thing with a little extra effort.

First some setup. After grabbing the latest JDK6 build I needed a database with a JDBC 4.0 driver. Some googling revealed that the also nifty Apache Derby database project is such a database, however only special daily builds have support turned on. Fair enough, it was only a download away and JDK6 is still in beta.

Finally, time for some code (ignoring imports, error handling and such):

public static void main(final String[] args)
        throws ClassNotFoundException, SQLException {
    Class.forName(EmbeddedDriver.class.getName());

    final Connection connection = DriverManager.getConnection(
        "jdbc:derby:test-database;create=true");

    final Statement statement = connection.createStatement();
    statement.execute("CREATE TABLE BOB"
            + "(ID INT NOT NULL GENERATED ALWAYS AS IDENTITY,"
            + " NAME VARCHAR(32))");

    connection.setAutoCommit(false);
    connection.setTransactionIsolation(TRANSACTION_SERIALIZABLE);

    final BobQuery query = connection.createQueryObject(BobQuery.class);

    final String name = "the Builder";
        
    final BobKeys key = query.addBob(name).get(0);
    final Bob bob = query.findBobByName(name).get(0);

    System.out.println("inserted = selected? " + key.id.equals(bob.id));

    query.close();
    statement.execute("DROP TABLE BOB");
    connection.commit();
    statement.close();
    connection.close();
}

public class Bob {
    public BigDecimal id;
    public String name;
}

@AutoGeneratedKeys
public class BobKeys {
    public BigDecimal id;
}

public interface BobQuery
        extends BaseQuery {
    @Update(sql = "INSERT INTO BOB(name) VALUES(?1)",
            keys = RETURNED_KEYS_DRIVER_DEFINED)
    DataSet addBob(final String name);

    @Select("SELECT * FROM BOB WHERE name = ?1")
    DataSet findBobByName(final String name);

    @Select("SELECT * FROM BOB")
    DataSet findAllBobs();

    @Update("DELETE FROM BOB")
    int removeAllBobs();
}

Everything worked!

(And Derby helpfully creates a scratch database in-place given the proper JDBC URL.)

There were some gotchas:

  • The Derby driver did not seem to use the new service feature at least for the embedded case shown here.
  • The type for primary key identifiers is BigDecimal, not Long as I guessed at. Improved javadocs would help here.
  • I had little luck with the {fieldName} syntax shown in the @Update annotation javadocs for auto-generated keys. I am unsure if the driver, the JDK, the javadocs or the coder is at fault.

JDBC 4.0 is particularly well thought-out for custom persistence layers. I suspect much was borrowed conceptually from Hibernate's excellent work. To use the common DAO pattern as an example, just consider insertion:

public int addBob(final Bob bob) {
    final DataSet keys = addBob(bob.getName());

    if (keys.isEmpty()) return 0;

    bob.id = keys.get(0).id;

    return keys.size();
}

So much boilerplate code saved, a real boon to the coder in the trenches; the code is very readable; no SQLException peppering the entire DAO layer. (Of course my curiosity rises: what does happen when the database cannot insert? — I need to read more on getSQLWarnings().)

JDBC 4.0 is nifty indeed.

UPDATE: As noted in one of the trackbacks, the Derby JDBC 4.0 driver now supports the service discovery mechanism. No more need to call Class.forName. Excellent.

Sunday, March 05, 2006

Using JNLP for a J2EE application client

In Moving the view away from the controller I talk about general ideas for separating the typical cohosting of a J2EE application (the service layer and below) from the view (JSPs, etc.).

Sun's own way of handling this is to make the client intimately familiar with the application beans. But this is the opposite of the direction I want to go in. Instead, I want to have the controller reside at the server, and the veiw in the client without any knowlege of beans and such.

Of course, this is the same as having any of a REST, SOAP, RPC or similar architectures, or all of them.

Presently, I am evaluating JBoss serialization v. REST-RPC to see how they compare for performance, reasonableness and ease of development, but am open to other suggestions.

My goal is to construct a demo client and server application with JNLP Swing at one end and standard J2EE servlets at the other. Fortunately for me, Sun gets me started and there are good examples by others.

Friday, March 03, 2006

IntelliJ IDEA 5175

Yah! Finally, an EAP build of what will become IntelliJ IDEA 6.0 that is usable for me. The previous EAP build (5162) had two problems for me:

  1. It threw exceptions a lot.
  2. Fatally, 5162 corrupted project settings files.

But the new 5175 build works great.

I like the newer way of handling views borrowed from Eclipse (I presume) but without the klunkiness feel of Eclipse perspectives (although the J2EE portion has some kinds to iron out: I get the J2EE view twice in the drop list).

I also see lib/emma.jar and lib/emma-agent.jar new with 5175 (perhaps also with 5162, but not in 5131). I have not found any UI yet for unit test code coverage, but it looks like IDEA is heading that direction.

Lastly, I also noticed lib/rt/org.eclipse.jdt.core.jar which is not in 5.1. I wonder what JetBrains is up to?

JUnit testing for exceptions

A JUnit pattern I find myself using very frequently is testing constructor and method inputs. Usually the first testcase I have for a new class is to test what happens in the constructor with null inputs. I believe in fail-fast coding principals and expect calls to quit as soon as they know there is no point in continuing. This helps me find bugs and other problems quickly during development rather than slowly during deployment.

So my typical test looks like this. For some class Foo whose constructor takes a single non-null parameter, bar, and which throws an IllegalArgumentException otherwise, I check for the name of the missing parameter in the exception message (as a convention):

 1 /**
 2  * Test {@link Foo#Foo(String)} for {@code null} <var>bar</var>.
 3  *
 4  * @throws Exception if unexpected
 5  */
 6 public void testFooForNullBar()
 7         throws Exception {
 8     try {
 9         new Foo(null);
10         fail("Did not throw");
11 
12     } catch (final IllegalArgumentException e) {
13         assertExceptionMessageContains(e, "bar");
14     }
15 }

But what about assertExceptionMessageContains? It is very simple:

 1 /**
 2  * Assert that the given exception, <var>e</var>, constains the given
 3  * string, <var>s</var>, in its message failing with <var>message</var>
 4  * otherwise.
 5  *
 6  * @param message the failure message
 7  * @param e the exception
 8  * @param s the string in the message
 9  */
10 protected static void assertExceptionMessageContains(final String message,
11         final Exception e, final String s) {
12     assertTrue(message, e.getMessage().contains(s));
13 }
14 
15 /**
16  * Assert that the given exception, <var>e</var>, constains the given
17  * string, <var>s</var>, in its message.
18  *
19  * @param e the exception
20  * @param s the string in the message
21  */
22 protected static void assertExceptionMessageContains(final Exception e,
23         final String s) {
24     assertExceptionMessageContains(
25             "Exception missing message: " + s + ": " + e, e, s);
26 }

Originally I threw NullPointerException from my constructors when encountering missing parameters, but over time I changed to IllegalArgumentException as more descriptive, and also so that any NullPointerException would always indicate something unexpected from the JVM.

Tuesday, February 28, 2006

Using Java 5 enums for the Command Pattern

Perhaps posted about elsewhere (my Google search did not turn up what I was looking for), one of the best uses for Java 5 enums is to implement the well-known Command Pattern.

Just one simple example with two commands, START and FINISH, and a simple execution parameter, sessionId:

/**
 * Demonstrates using JDK5 {@code enum}s for the Command Pattern.
 * 
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 */
public enum CommandEnum {
    /**
     * The {@code START} command.
     */
    START() {
        @Override
        public void execute(final SessionId sessionId) {
            System.out.println("Start: " + sessionId);
        }
    },
    /**
     * The {@code FINISH} command.
     */
    FINISH() {
        @Override
        public void execute(final SessionId sessionId) {
            System.out.println("Finish: " + sessionId);
        }
    };
    
    /**
     * Executes the command.
     */
    public abstract void execute(final SessionId sessionId);
    
    public static void main(final String[] args) {
        final SessionId mySessionId = new SessionId(13);
        
        for(final CommandEnum command : CommandEnum.values())
            command.execute(mySessionId);
        
        final SessionId yourSessionId = new SessionId(31);
        
        CommandEnum.valueOf("START").execute(yourSessionId);
        CommandEnum.valueOf("FINISH").execute(yourSessionId);
    }
    
    private static final class SessionId {
        private final int id;
        
        SessionId(final int id) {
            this.id = id;
        }
        
        @Override
        public String toString() {
            return Integer.toString(id);
        }
    }
}

A nice benefit of this use of enum is that one need not refactor existing code to take advantage. Use the enums with the Adapter or Facade Patterns and replace the bodies of execute() with forwarding calls to the original code implementations. Then new code can use the Command Pattern while existing code can continue to use the (possibly @Deprecated) original calls.