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>();
    }
}