Tuesday, December 27, 2005

Emulating static import

It may seem a trivial feature in JDK5, but static import is growing on me. It especially helps me read code to see the flow of method calls without package prefixes.

So at work I'm on a JDK1.4.2 project and miss static import. The solution is quite simple: I put same-named private static methods at the bottom of my class files to emulate the static import, thus:

import javax.swing.UIManager;

/**
 * A toy example: not production code.
 * <p/>
 * Throwing <code>RuntimeException</code> is in poor taste.
 */
public class TopLevel {
    static {
        // Set up font smoothing
        System.setProperty("swing.aatext", "true");

        try {
            setLookAndFeel("net.java.plaf.windows.WindowsLookAndFeel");

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

        } catch (final UnsupportedLookAndFeelException e) {
            throw new RuntimeException(e);

        } catch (final InstantiationException e) {
            throw new RuntimeException(e);

        } catch (final ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    // Real work goes here.

    // Simple forwarding to emulate static import:
    private static void setLookAndFeel(final String name)
            throws ClassNotFoundException,
            InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(name);
    }
}

It's not rocket science, but it makes my day just a little bit nicer.

Monday, December 19, 2005

New math functions in JDK6

I've been watching the releases of JDK6 closely and have noticed that the math facilities continue to mature. Following in the footsteps of java.lang.StrictMath in JDK5, I see that JDK6 adds more useful static methods (for each method, there are similar methods for floats):

double copySign(double magnitude, double sign)
Returns the first floating-point argument with the sign of the second floating-point argument.
int getExponent(double d)
Returns the unbiased exponent used in the representation of a double.
double nextAfter(double start, double direction)
Returns the floating-point number adjacent to the first argument in the direction of the second argument.
public static double nextUp(double d)
Returns the floating-point value adjacent to d in the direction of positive infinity.
double scalb(double d, int scaleFactor)
Return d × 2scaleFactor rounded as if performed by a single correctly rounded floating-point multiply to a member of the double value set.

The only drawback is that several common operations are still missing. I wish the JDK would provide the comprehensiveness of C's libm.

Wednesday, December 14, 2005

Reinventing the enum in Java

I'm working on a Java project which uses JDK 1.4.2, so I do not have the useful enum keyword available to me. What to do? Reinvent the enum, of course. I try following the pattern set by JDK5, suitable for JDK 1.4.2. Merry Christmas:

/**
 * <code>AbstractEnum</code> models <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Enum.html">the
 * JDK5 <code>enum</code> feature</a>.
 * <p/>
 * Extending classes should follow this example: <pre>
 * public class Suit
 *         extends AbstractEnum {
 *     public static final Suit CLUBS = new Suit("CLUBS");
 *     public static final Suit DIAMONDS = new Suit("DIAMONDS");
 *     public static final Suit HEARTS = new Suit("HEARTS");
 *     public static final Suit SPADES = new Suit("SPADES");
 *
 *     public static Suit[] values() {
 *          return (Suit[]) values0(Suit.class, new Suit[count(Suit.class)]);
 *     }
 *
 *     public static Suit valueOf(final String name) {
 *         return (Suit) valueOf0(Suit.class, name);
 *     }
 *
 *     private Suit(final String name) {
 *         super(name);
 *     }
 * }</pre>
 *
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 * @version $Id$
 * @since Dec 14, 2005 6:32:23 PM
 */
public abstract class AbstractEnum
        implements Comparable {
    private static final Map ALL_VALUES_BY_NAME = new HashMap(4);
    private static final Map ALL_VALUES_BY_ORDINAL = new HashMap(4);
    private static final Map ALL_COUNTS = new HashMap(4);

    /**
     * The ordinal of this enumeration constant (its position in the enum
     * declaration, where the initial constant is assigned an ordinal of zero).
     * <p/>
     * Most programmers will have no use for this field.  It is designed for use
     * by sophisticated enum-based data structures.
     */
    private final int ordinal = createNextOrdinal(getClass());

    /**
     * The name of this enum constant, as declared in the enum declaration. Most
     * programmers should use the {@link #toString} method rather than accessing
     * this field.
     */
    private final String name;

    /**
     * Gets all enum values of type <var>clazz</var> into <var>array</var>.  Use
     * {@link #count(Class)} to size the array parameter.
     * <p/>
     * Concrete subclasses <em>should</em> provide <code>values()</code> which
     * follows the example:
     * <pre>
     * public static Suit[] values() {
     *     return (Suit[]) valuesOf(Suit.class, new Suit[count(Suit.class)]);
     * }</pre>
     *
     * @param clazz the enum type
     * @param array the array
     *
     * @return the enum values
     *
     * @throws ClassCastException if <var>clazz</var> is not an enum class
     */
    protected static AbstractEnum[] values0(final Class clazz,
            final AbstractEnum[] array) {
        checkClassIsEnum(clazz);

        int i = 0;

        for (final Iterator valueIt = getValuesByOrdinal(clazz).iterator();
                valueIt.hasNext(); ++i)
            array[i] = (AbstractEnum) valueIt.next();

        return array;
    }

    /**
     * Gets the count of enums of type <var>clazz</var>, zero (0) if none.
     *
     * @param clazz the enum type
     *
     * @return the enum count
     *
     * @throws ClassCastException if <var>clazz</var> is not an enum class
     */
    protected static int count(final Class clazz) {
        checkClassIsEnum(clazz);

        return ALL_COUNTS.containsKey(clazz)
                ? ((Integer) ALL_COUNTS.get(clazz)).intValue()
                : 0;
    }

    /**
     * Gets an enum with the given <var>name</var>.
     * <p/>
     * Concrete subclasses <em>should</em> provide <code>valuesOf(String)</code>
     * which follows the example:
     * <pre>
     * public static Suit valueOf(final String name) {
     *     return (Suit) valueOf(Suit.class, name);
     * }</pre>
     *
     * @param clazz the enum class
     * @param name the enum name
     *
     * @return the corresponding enum value
     *
     * @throws ClassCastException if <var>clazz</var> is not an enum class
     * @throws IllegalArgumentException if <var>name</var> is not an enum name
     */
    protected static AbstractEnum valueOf0(final Class clazz,
            final String name)
            throws IllegalArgumentException {
        checkClassIsEnum(clazz);

        final Map values = getValuesByName(clazz);

        if (values.containsKey(name))
            return (AbstractEnum) values.get(name);

        throw new IllegalArgumentException(name);
    }

    /**
     * Constructs a new <code>AbstractEnum</code> with the given
     * <var>name</var>.
     *
     * @param name the name of this enum constant, which is the identifier used
     * to declare it
     */
    protected AbstractEnum(final String name) {
        this.name = name;

        getValuesByName(getClass()).put(name, this);
        getValuesByOrdinal(getClass()).add(this);
    }

    /**
     * Returns the name of this enum constant, exactly as declared in its enum
     * declaration.
     * <p/>
     * <b>Most programmers should use the {@link #toString} method in preference
     * to this one, as the toString method may return a more user-friendly
     * name.</b>  This method is designed primarily for use in specialized
     * situations where correctness depends on getting the exact name, which
     * will not vary from release to release.
     *
     * @return the name of this enum constant
     */
    public String name() {
        return name;
    }

    /**
     * Returns the ordinal of this enumeration constant (its position in its
     * enum declaration, where the initial constant is assigned an ordinal of
     * zero).
     * <p/>
     * Most programmers will have no use for this method.  It is designed for
     * use by sophisticated enum-based data structures.
     *
     * @return the ordinal of this enumeration constant
     */
    public int ordinal() {
        return ordinal;
    }

    // Object

    /**
     * Throws CloneNotSupportedException.  This guarantees that enums are never
     * cloned, which is necessary to preserve their "singleton" status.
     *
     * @return (never returns)
     *
     * @throws CloneNotSupportedException if called
     */
    protected Object clone()
            throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    /**
     * Returns the name of this enum constant, as contained in the declaration.
     * This method may be overridden, though it typically isn't necessary or
     * desirable.  An enum type should override this method when a more
     * "programmer-friendly" string form exists.
     *
     * @return the name of this enum constant
     */
    public String toString() {
        return name;
    }

    // Comparable

    /**
     * Compares this enum with the specified object for order.  Returns a
     * negative integer, zero, or a positive integer as this object is less
     * than, equal to, or greater than the specified object.
     * <p/>
     * Enum constants are only comparable to other enum constants of the same
     * enum type.  The natural order implemented by this method is the order in
     * which the constants are declared.
     */
    public int compareTo(final Object o) {
        if (!getClass().equals(o.getClass()))
            throw new ClassCastException(o.getClass().toString());
        return ordinal - ((AbstractEnum) o).ordinal;
    }

    private static Map getValuesByName(final Class clazz) {
        final Map values;

        if (ALL_VALUES_BY_NAME.containsKey(clazz))
            values = (Map) ALL_VALUES_BY_NAME.get(clazz);
        else
            ALL_VALUES_BY_NAME.put(clazz, values = new HashMap(8));

        return values;
    }

    private static SortedSet getValuesByOrdinal(final Class clazz) {
        final SortedSet values;

        if (ALL_VALUES_BY_ORDINAL.containsKey(clazz))
            values = (SortedSet) ALL_VALUES_BY_ORDINAL.get(clazz);
        else
            ALL_VALUES_BY_ORDINAL.put(clazz, values = new TreeSet());

        return values;
    }

    private static int createNextOrdinal(final Class clazz) {
        final int count = count(clazz);

        ALL_COUNTS.put(clazz, new Integer(count + 1));

        return count;
    }

    private static void checkClassIsEnum(final Class clazz) {
        if (!AbstractEnum.class.isAssignableFrom(clazz))
            throw new ClassCastException(clazz.toString());
    }
}

Tuesday, November 22, 2005

The Extensible Enum Pattern in Java

There is a long history of the enum pattern in Java. What I have seen and used several times on different projects is a variant which we called the Extensible Enum Pattern. My fellow ex-ThoughtWorker, Andrew McCormick, first showed it to me.

Here is what I wrote the PCGen developer's list about this pattern when the question arose about processing program-defined and user-defined tokens together:

We have a set of conditions based on integer codes, some which we define themselves, others which are read from 3rd-party files and cannot all be known ahead of time.

The basic class for our extensible enum looks like this:

public class Status {
    private final int code;
    private final String remark;

    private Status(final int code, final String remark) {
        if (null == remark) throw new NPE;

        this.code = code;
        this.remark = remark;
    }
}

Ok, so the object is immutable: there are no setters or editable fields. That is the first step towards being an enum. And so far there are no public way to create new ones. Lets open the class and add a factory method:

    private static final Map CODES = new HashMap();

    public static Status create(final int code, final String remark) {
        final Integer key = new Integer(code);
        final Status status;

        if (!CODES.containsKey(key))
            CODES.put(key, status = new Status(code, remark));
        else
            status = (Status) CODES.get(key);

        return status;
    }

Now we have the other half of being an enum: no two instances of the same value are distinguishable. Whenever you try to create a new enum, if there is already an instance with the same code, you get back that instance rather than a new instance. (However, as the remark is just satellite data, not part of the identity of Status, you can see that you also get back the original remark.) Let's reinforce this message, and open the class again:

    public int hashCode() {
        return code;
    }

    public boolean equals(final Object o) {
        if (this == o) return true;
        if (null == o) return false;
        if (getClass() != o.getClass()) return false;

        return code == ((Status) o).code;
    }

Lastly, let's open the class one final time to prepopulate it with our defined instances (be careful to initialize CODES before creating static instances or you'll get a NPE when trying to access the cache):

    public static final Status SUCCESS = create(0, "Success");
    public static final Status BARNEY_DIED = create(-10,
            "Barney died: please reinsert purple dinosaur.");
    public static final Status OLL_KORRECT = create(10,
            "All your answers are correct!");

Now in code, I use Status like this:

    if (somethingHorribleHappened())
        return Status.BARNEY_DIED;
    else
        return Status.create(readCodeFromElsewhere(),
                "Out of body experience: external status");

So that we got well-defined static instances for internal codes, and can generate new instances as required for external codes.

At bottom, I'll paste in a JDK5 version (generics, auto-boxing, annotations) along with some business methods. Note that the new JDK enum feature is not extensible. Otherwise, it is a thing of beauty, and in fact my next revision of this class for my client will model the JDK enum class more closely but retain the extensible property.

And lastly, the same thing updated for JDK5 and with some comments:

import java.util.HashMap;
import java.util.Map;

/**
 * {@code Status} represents extensible enums for status codes.
 *
 * @author <a href="mailto:binkley@alumni.rice.edu">B. K. Oxley (binkley)</a>
 */
public class Status {
    private static final Map<Integer, Status> CODES
            = new HashMap<Integer, Status>();

    /**
     * An unremarkable success.
     */
    public static final Status SUCCESS = create(0, "Success");
    /**
     * An unknown failure.
     */
    public static final Status UNKNOWN_FAILURE = create(-1, "Unknown failure");

    /**
     * Creates a new {@code Status} or reuses an existing instance for a given
     * <var>code</var>.
     *
     * @param code the status code
     * @param remark the status remark
     *
     * @throws NullPointerException if <var>remark</var> is {@code null}
     */
    public static Status create(final int code, final String remark) {
        final Status status;

        if (!CODES.containsKey(code))
            CODES.put(code, status = new Status(code, remark));
        else
            status = CODES.get(code);

        return status;
    }

    private final int code;
    private final String remark;

    private Status(final int code, final String remark) {
        if (null == remark) throw new NullPointerException();

        this.code = code;
        this.remark = remark;
    }

    public int getCode() {
        return code;
    }

    public String getRemark() {
        return remark;
    }

    /**
     * Checks if a success or failure status.  All non-negative codes
     * are successful.
     *
     * @return {@code true} if a success status
     */
    public boolean isSuccess() {
        return 0 <= code;
    }

    /**
     * Checks if {@link #getRemark()} is meaningful.  All non-zero codes
     * are remarkable.
     *
     * @return {@code true} if {@link #getRemark()} is useful
     */
    public boolean isRemarkable() {
        return 0 != code;
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns <em>"(code) remark"</em>.
     */
    @Override
    public String toString() {
        return "(" + code + ") " + remark;
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Considers only {@link #code} for equality.
     */
    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (null == o) return false;
        if (getClass() != o.getClass()) return false;

        return code == ((Status) o).code;
    }

    /**
     * {@inheritDoc}
     * <p/>
     * Returns {@link #code} as the hash code.
     */
    @Override
    public int hashCode() {
        return code;
    }
}

Tuesday, November 15, 2005

Spashscreen for Java startup

I'm not sure how long it's been there (at least since September, when this post came out), but java now supports a splash screen option on startup:

-splash:<imagepath>
              show splash screen with specified image

Nifty.

Saturday, October 22, 2005

Qt for Java

Aaron Seigo writes a good amount about the TrollTech developer's social in San Diego. The part that made my ears perk up:

haavard announced that by Q1-06 they'll be releasing a tech preview of java bindings for qt4 that will be officially supported. wow.

Wow indeed.

Friday, October 21, 2005

Jeff Biggler's Tack Filters

I heard about this gem of an article on the XP Yahoo! Groups list, Tact Filters. As any of my friends will point out, my native tact filter is applied to the incoming direction. Age has granted me an add-on tact filter for the outgoing direction, not as operative as the native filter but better than none.

Monday, October 17, 2005

Ruby in Eclipse

An interesting article from IBM on the Ruby extension for Eclipse, Using the Ruby Development Tools plug-in for Eclipse. The blurb:

This article introduces using the Ruby Development Tools (RDT) plug-in for Eclipse, which allows Eclipse to become a first-rate Ruby development environment. Ruby developers who want to learn how to use the rich infrastructure of the Eclipse community to support their language will benefit, as will Java™ developers who are interested in using Ruby.

Fortunately, the article is more than just a description and includes setup and all that. And what pretty screenshots!

Wednesday, October 12, 2005

Agile leadership

One of the things that draws me to agile programming styles is the agile approach to leadership.

Waterfall processes naturally fit within a top-down organization where leadership is a direct chain of control in the shape of a pyramid. The exemplar of waterfall leadership is a military organization.

Agile leadership follows from agile processes. It emphasizes change, collaboration and consultation. To adapt is more important than to plan; to listen is more important than to order; to trust is more important than to manage. The shape is that of a network.

But agile leadership is not the opposite of waterfall leadership. A good leader keeps both in mind and applies the best principle to the problem at hand.

For example, new junior programmers are often bewildered by the array of technical approaches available for a given problem. In an agile environment, pair the young Jedi with a senior developer who can share his craft and training.

However, there may not be a senior developer available. Lacking a suitable guide, it is better to task the apprentice with short, straight-forward steps—spell out a likely solution that the junior programmer can learn from as he codes, and provide supervision as requested.

Again, a problem arises: what sort of supervision? If possible, instill in the new peer that you trust him to follow simple instructions but that you are approachable for questions and suggestions. The goal is not to simply train the fingers to type good code, but also teach the mind good values. I believe those values to be agile ones; you may believe otherwise.

None of this is controversial, yet I encounter such mentoring more often with agile leadership than with waterfall leadership. Perhaps it is more a measure of where I worked than how I worked, but I prefer to believe the manifesto.

The big picture

Am I a details person? The impression of most people is that I am; this blog certainly is detail-oriented. But I would argue otherwise.

I approach most topics as scaling problems. If you are talking about atoms, the appropriate level of detail is the atomic; if you are talking about aggregates, the appropriate level of detail is small but at the macro scale; if you are talking about galaxies, the appropriate level of detail is stars and dust.

On this blog, most entries are detail-oriented simply because small domains are easier to describe than large domains and the answers are more satisfactory and complete. (Even so, I often miss interesting points; I am grateful for comments.)

Contrast the small scale of algorithms where behaviors can in many cases be analyzed fully with the large scale of company-wide systems where behaviors are imprecise and many factors difficult to analyze come into play.

For a short blog entry written to a general audience, I would rather approach an algorithm as the level of detail. I believe it is more satisfying for the reader and less time-consuming for the author. For a white paper (such as this one I wrote while at EBS) I have more freedom in exposition to tackle a larger topic. Perhaps more opportunities will come for me to write about the bigger picture.

Arrays and Collections

Keith Devens makes a good point of recommending Arrays.asList(...) over hand-crafted lists. Thus he suggests that in place of:

List<Foo> foolist = new ArrayList<Foo>();
foolist.add(foo);
return foolist;

You instead use:

return Arrays.asList(foo);

This has much to recommend it, especially conciseness and clarity. However, as the hawker on late night TV says, But there's more!

In addition to the useful Arrays class of static helper methods, there is Collections which has more useful static helper methods. So the example could have also been written as:

return Collections.singletonList(foo);

What's the difference? This is an interesting question. There is no way to select between Arrays and Collections without further information.

If the requirement were to return an unmodifiable view, then the easy route is:

return Collections.singletonList(foo);

Which is an even more clear way to express the intention of the code than Arrays.toList—the singleton pattern is one of the first grokked by any programmer. What if the code fragment were part of this method?

/**
 * Returns a modifiable list of just the topmost foo.
 *
 * @return Modifiable list containing just the topmost foo
 */
public List<Foo> copyTopFooAsList() {
    return ???;
}

Now it is clear from the javadocs for Arrays.asList that this is not quite what we want:

Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray.

And clearly Collections.singletonList(T) is not right either—when is a proper singleton modifiable? And Collections.toArray is clearly useful, but not what we are looking for (it returns an array, not a list).

After some thought, the solution is not hard to find: look at the constructors for ArrayList, and at ArrayList(Collection) in particular. Although the javadocs do not explicitly say copies from the input, they do hint at that (and a quick peek at the source code confirms it is so):

Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.

So the solution becomes:

return new ArrayList(Collections.singleton(foo));

A handy one-liner to keep in the back pocket for future use.

Tuesday, October 11, 2005

Better GC in JDK6 (Mustang)

As noted in OSnews, IBM has a great article on GC in the Java VM entitled Java Urban Legends. One of the developments in the ever-improving JVM really caught my eye:

Escape analysis is an optimization that has been talked about for a long time, and it is finally here -- the current builds of Mustang (Java SE 6) can do escape analysis and convert heap allocation to stack allocation (or no allocation) where appropriate. The use of escape analysis to eliminate some allocations results in even faster average allocation times, reduced memory footprint, and fewer cache misses. Further, optimizing away some allocations reduces pressure on the garbage collector and allows collection to run less often.

Escape analysis can find opportunities for stack allocation even where it might not be practical to do so in the source code, even if the language provided the option, because whether a particular allocation gets optimized away is determined based on how the result of an object-returning method is actually used in a particular code path. The Point returned from getLocation() may not be suitable for stack allocation in all cases, but once the JVM inlines getLocation(), it is free to optimize each invocation separately, offering us the best of both worlds: optimal performance with less time spent making low-level, performance-tuning decisions.

The referenced code before optimization:

public double getDistanceFrom(Component other) {
    Point otherLocation = new Point(other.x, other.y);
    int deltaX = otherLocation.x - location.x;
    int deltaY = otherLocation.y - location.y;
    return Math.sqrt(deltaX*deltaX + deltaY*deltaY);
}

And after:

public double getDistanceFrom(Component other) {
    int tempX = other.x, tempY = other.y;
    int deltaX = tempX - location.x;
    int deltaY = tempY - location.y;
    return Math.sqrt(deltaX*deltaX + deltaY*deltaY);
}

A nice win for Sun's JVM, to be sure.

Thursday, October 06, 2005

Testing protected methods with JUnit 4

One of the pains of JUnit is testing protected methods. Public methods offer no impediment to testing, and private methods in well-designed classes can be ignored as implementation details called by the public methods. But protected methods are important for frameworks and central to the Template Method pattern; they need testing.

The most common ways to test protected methods that I've seen are to invoke the protected method with reflection, to use a private inner helper class which extends the class under test, and similarly to extend the class under test and change the access of the protected methods to public. All have their drawbacks.

Enter JUnit 4. No longer must test classes extend TestCase. Using annotations, the test framework finds and runs your test methods without inheritance, and static imports keep calls to assertTrue and friends looking clean and tidy.

Your test class itself can extend the class under test and access the protected methods without the need for reflection or a second, helper class. This is another blow struck for small, clean code thanks to JDK 5.

UPDATE: As Sam in the comments pointed out, one could just put the tests in the same package as the class under test. For silly reasons, I left this out of the list of workarounds.

Tuesday, September 27, 2005

XP cards in real life

Charles Miller has a great shot of XP-style cards in use, tacked up on the Wall of Death. As he describes:

When, as we do, you write your specs on a wiki, keep track of your development tasks in an issue tracker, and eventually ship products that only exist as bits downloaded from a server, it’s very easy to forget how much psychological impact physical objects can have.

Data exists in some ether that your mind never really has to deal with completely. Physical things have presence. They take up space. They can arrest your vision. When you move them they stay moved. You can fold, spindle and mutilate them as you wish.

Monday, September 19, 2005

Building JDK 5 projects with Maven 2

I had a difficult time working out from the Apache Maven 2 site documentation how to build my JDK 5 projects with m2. I found the spot in the documentation for configuring plugins and reasoned that the Java compilation goal must be connected to a plugin, but did not see exactly how to tie it all together.

After several futile Google attempts, I finally hit upon trying pom.xml source target 1.5 and found this JIRA issue covering an example and including an attached pom.xml. Using the example, a basic POM (what was previously project.xml with Maven 1) is:

<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>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.5</source>
          <target>1.5</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

I got this by running the suggested new project generator:

m2 archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app

And adding the needed <build/> section.

Serendipity

I've been looking a lot at continuations in recent posts. Along came this post on Jetty 6 continuations and the serendipity is enough to make me shiver. Are continuations finally making it into the mainstream?

I had the opportunity recently to talk with someone new to continuations about their clever usefulness. This Jetty 6 article is just the sort of example I wish I had had in my back pocket for that chat.

UPDATE: An interesting observation about Jetty's use of threads and continuations.

Thursday, September 15, 2005

Template legerdermain

Following up on yesterday's post, I worked out how to capture the return value for a continuation, that is, a future computation.

(Aside: This raised a question in my mind: what should be the behavior of asking for the result of a computation which has not yet taken place? In my prototype, I return a default constructed value (e.g., 0 for an int). Another option might be to raise an appropriate exception as it is likely a programming error. Yet another is to provide a sentinal value or a predicate to ask the state of the computation. That last choice is interesting: if the continuation changes to a different context before finishing, the computation could be half-completed or even discarded. Questions for another day.)

The new sample main is:

#include <cstdlib>
#include <iostream>

#include "continuations.h"

static int
increment (int id, int *n)
{
  int m = *n;
  std::cout << id << " thinks: " << *n << std::endl;
  ++*n;
  return m;
}

int
main (void)
{
  int initial_value = 0;

  continuation<void> main_uc;
  // TODO: Why not deduce from the return type of increment?
  continuation<int> inc0_uc (main_uc, increment, 1, &initial_value);
  continuation<int> inc1_uc (inc0_uc, increment, 2, &initial_value);

  std::cout << "1 said: " << static_cast<int> (inc0_uc) << std::endl;
  std::cout << "2 said: " << static_cast<int> (inc1_uc) << std::endl;

  main_uc.switch_to (inc1_uc);

  std::cout << "All done: " << initial_value << std::endl;
  std::cout << "1 says: " << static_cast<int> (inc0_uc) << std::endl;
  std::cout << "2 says: " << static_cast<int> (inc1_uc) << std::endl;

  return EXIT_SUCCESS;
}

The header is somewhat hairy, however:

#ifndef _CONTINUATION_H
#define _CONTINUATION_H

#include <stdexcept>

#include <errno.h>
#include <string.h>
#include <ucontext.h>

#define STACK_SIZE 4096

template <typename R> class continuation;

class continuation_base : public ucontext_t {
  char stack[STACK_SIZE];

protected:
  continuation_base () {
    initialize ();
  }

  template<typename R1>
  continuation_base (continuation<R1> &next) {
    initialize ();
    uc_link = &next;
  }

public:
  template<typename R1>
  int switch_to (continuation<R1> &next) {
    return swapcontext (this, &next);
  }

private:
  void initialize () {
    if (getcontext (this) < 0)
      throw std::runtime_error (strerror (errno));

    uc_stack.ss_sp = stack;
    uc_stack.ss_size = sizeof stack;
  }
};

template<typename R>
void apply (R (*lambda) (), R *r) {
  *r = lambda ();
}

template<typename R, typename T0>
void apply (R (*lambda) (T0), R *r, T0 t0) {
  *r = lambda (t0);
}

template<typename R, typename T0, typename T1>
void apply (R (*lambda) (T0, T1), R *r, T0 t0, T1 t1) {
  *r = lambda (t0, t1);
}

template<typename R>
class continuation : public continuation_base {
  R value;

public:
  continuation () { }

  template<typename R1>
  continuation (continuation<R1> &next, R (*lambda) ())
    : continuation_base (next) {
    void (*fp) (R (*) (), R *) = apply<R>;
    makecontext (this,
                 reinterpret_cast<void (*) (void)> (fp),
                 2, lambda, &value);
  }

  template<typename R1, typename T0>
  continuation (continuation<R1> &next, R (*lambda) (T0), T0 t0)
    : continuation_base (next) {
    void (*fp) (R (*) (T0), R *, T0) = apply<R, T0>;
    makecontext (this,
                 reinterpret_cast<void (*) (void)> (fp),
                 3, lambda, &value, t0);
  }

  template<typename R1, typename T0, typename T1>
  continuation (continuation<R1> &next, R (*lambda) (T0, T1),
                T0 t0, T1 t1)
    : continuation_base (next) {
    void (*fp) (R (*) (T0, T1), R *, T0, T1) = apply<R, T0, T1>;
    makecontext (this,
                 reinterpret_cast<void (*) (void)> (fp),
                 4, lambda, &value, t0, t1);
  }

  operator R () { return value; }
};

template<>
class continuation<void> : public continuation_base
{
public:
  continuation () { }

  template<typename R1>
  continuation (continuation<R1> &next) : continuation_base (next) { }
};

#endif /* _CONTINUATION_H */

Two techniques of note are the specialization for void return and moving non-return value-related code into a shared base class—a common trick when parameterizing return types—, and the use of apply handle the return value from lambda in the continuation.

makecontext takes a void (*) (void) function pointer for the program text of the ucontext_t, which requires a cast of apply. I found that simply:

makecontext (this,
             reinterpret_cast<void (*) (void)> (&apply<int, int, int *>),
             4, lambda, &value, t0, t1);

would not compile with GCC 3.3.5. This is an area of C++ where my fu is insufficient to know at sight if my code is legal—although I presume it is. So I resorted to local variable, fp, for the cast and suddenly GCC was satisfied (see above).

So the short of it is that now I can interrogate my continuation for its computed value.

Wednesday, September 14, 2005

Continuations in C++, a starting point

Starting from the example in the GNU C Library info pages on System V contexts, I cooked up a starting point for continuations in C++. Usage is simple:

#include <stdio.h>

#include "continuation.h"

static void
increment (int *n)
{
  printf ("Nothing interesting: %d\n", *n);
  ++*n;
}

int
main (void)
{
  int initial_value = 0;

  continuation main_uc;
  continuation inc0_uc (main_uc, increment, &initial_value);
  continuation inc1_uc (inc0_uc, increment, &initial_value);

  main_uc.switch_to (inc1_uc);

  printf ("I'm back: %d\n", initial_value);

  return 0;
}

Program output is as expected:

Nothing interesting: 0
Nothing interesting: 1
I'm back: 2

That is, the first frame runs increment; the second frame does the same; and the last frame runs main from where it left off after jumping to the first frame: a continuation.

The header:

#ifndef _CONTINUATION_H
#define _CONTINUATION_H

#include <stdexcept>

#include <errno.h>
#include <string.h>
#include <ucontext.h>

// Tricky to work out without cpu-os-specific information:
#define STACK_SIZE 4096

class continuation : public ucontext_t
{
  char stack[STACK_SIZE];

public:
  continuation () {
    initialize ();
  }

  continuation (continuation &next) {
    initialize ();
    uc_link = &next;
  }

  continuation (continuation &next, void (*lambda) (void)) {
    initialize ();
    uc_link = &next;
    set_lambda (lambda);
  }

  template<typename T0>
  continuation (continuation &next, void (*lambda) (T0), T0 t0) {
    initialize ();
    uc_link = &next;
    set_lambda (lambda, t0);
  }

  int switch_to (continuation &next) {
    return swapcontext (this, &next);
  }

private:
  void initialize () {
    if (getcontext (this) < 0)
      throw std::runtime_error (strerror (errno));

    uc_stack.ss_sp = stack;
    uc_stack.ss_size = sizeof stack;
  }

  void set_lambda (void (*lambda) ()) {
    makecontext (this, lambda, 0);
  }

  template<typename T0>
  void set_lambda (void (*lambda) (T0), T0 t0) {
    makecontext (this, (void (*) (void)) (lambda), 1, t0);
  }
};

#endif /* _CONTINUATION_H */

Tuesday, September 13, 2005

My kind of technical writer

Sam Ruby writes about continuations for old-time programmers like me. Anyone who starts of a technical article with:

This essay is for people who, in web years, are older than dirt.

and after the first example observes:

If you now look around, you will notice that all the tadpoles that never really programmed in C have jumped out of the pond.

is my kind of author. And I love that he drifts from language to language for his examples. Great article. Good ole' call/cc.

Sunday, September 11, 2005

Agile abuse

Alistair Cockburn posts an interesting link to the XP Yahoo! Group entitled Iterations harmful?. His synopsis:

I finally got around to writing up my recent experiences in seeing how people abuse iterations, user stories and velocity to hide the ways they are damaging their projects.

This promptly led to a rather length chain of posts wherein many good suggestions were offered and incorporated. Overall quite a nice article on agile practises and how to make practical use of them.

Pointing fingers

There is a series of defects in IntelliJ 5.0 on Linux that go like this:

I can not open 'Appearance' settings in IDE Settings (File -> Settings -> Appearance).
The main problem is that it is system-specific bug. On other PCs everything works fine.
No appearance settings window opens and exception listed below appears in log:

2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - Error during dispatching of java.awt.event.MouseEvent[MOUSE_RELEASED,(194,244),button=1,modifiers=Button1,clickCount=1] on dialog9
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - IntelliJ IDEA 5.0 Build #3436
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - JDK: 1.5.0_04
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - VM: Java HotSpot(TM) Client VM
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - Vendor: Sun Microsystems Inc.
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - OS: Windows XP
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - Last Action: ShowSettings
2005-08-03 13:39:45,250 [ 733235] ERROR - com.intellij.ide.IdeEventQueue - Error during dispatching of java.awt.event.MouseEvent[MOUSE_RELEASED,(194,244),button=1,modifiers=Button1,clickCount=1] on dialog9
java.lang.ArrayIndexOutOfBoundsException: -2147483648
at sun.font.CMap$CMapFormat4.getGlyph(CMap.java:540)

The defect status is a discouraging Won't Fix. The developer comment is:

This is identified Sun JRE issue: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6247425

Ok, what does that SUN bug say?

Bug ID: 6247425
Votes 0
Synopsis Unhandled OutOfBounds exception while parsing TTF files
Category java:classes_2d
Reported Against b28
Release Fixed mustang(b33)
State Closed, fixed
Related Bugs
Submit Date 29-MAR-2005
Description
For some TTF files with CMAP format 4 i am seeing following exception:

java.lang.ArrayIndexOutOfBoundsException: -2147483648
        at sun.font.CMap$CMapFormat4.getGlyph(CMap.java:547)
        at sun.font.TrueTypeGlyphMapper.charToGlyph(TrueTypeGlyphMapper.java:115)
        at sun.font.CharToGlyphMapper.canDisplay(CharToGlyphMapper.java:40)
        at sun.font.Font2D.canDisplay(Font2D.java:426)
        at java.awt.Font.canDisplay(Font.java:1780)

 xxxxx@xxxxx  2005-03-29 16:25:48 GMT
Work Around
N/A
Evaluation
Examining fonts with ttfdump it seems they are malformed - 
entrySelector=1024 and searchRange=8192 while segCount=22
(we read same numbers in CMap.java).

This is weird because according to spec these numbers are derived from 
segCount. Proper values for table like this are 4 and 32 - so it looks like byteorder is wrong.

We may either reject such fonts as malformed or simply ignore them and
derive appropriate values ourselves. (windows shows these fonts with 
font viewer)

In any case parsing CMAP we should catch all potential exceptions.

 xxxxx@xxxxx  2005-03-29 16:25:48 GMT

So, apparently, I have malformed fonts installed on my Linux box. But notice SUN's status: Closed, fixed, albeit in a future release.

IntelliJ's status of Won't fix is just stupid. Just surround the exception-throwing code with a handler and warn the user about broken fonts. This is infinitely better than crashing. And for bonus points, backport the JDK 6 fix to a replacement class so that IDEA can handle the broken fonts. What's so hard about that?

UPDATE: I just tried out Mustang b51 (JDK 1.6 beta) to see if the bug was indeed fixed. Again IDEA crashes. At least there is console output:

binkley@hermes:~/opt/idea/bin>java: ../../../src/share/native/sun/awt/font/t2k/t1.c:2178: tsi_T1GetGlyphIndexFromAdobeCode: Assertion `0' failed.

Time to go update the Closed, fixed SUN bug.

UPDATE: That was quick! Phil, the nice man from SUN, mailed me later after I posted the new bug:

6247425 was a bug in a TrueType font.
The message here is a bug in a Type1 font.
They are unrelated except that it sounds like you hit the first
bug before you could reach the second bug and now you can reach
the second bug.
I recall that SuSE 9.2 Pro has a *LOT* of fonts of variable quality.
We looked at those fonts - and there were a few - that caused a crash
in the same area as this - it was bug 6229389 ixed it in mustang b33.

I especially appreciate that he provided me means further in the mail to track down the bad font. Thank you, Phil!

Saturday, September 10, 2005

This is real programming

Real men port; wimps reinvent the wheel.

At work we have an extensive JNI layer for our Java applications to work with a series of cooperating Windows/Linux processes which implement our own file system and support services (remote printing, user/group management, etc). Sadly, we do not use Cygwin and are saddled with extensive #ifdef/#else/#endif code based on platform. (It also does not help that Windows was our first target platform.)

elliotth's outstanding Terminator program using Java/JNI/Cygwin would have been a good model for us in many respects had it been known earlier. It's a well thought out design and a beautiful application.

Friday, September 09, 2005

Off topic but not off key

Stephen Wolfram presents a new kind of programming, WolframTones. This would have been a cool way to cheat back when I was a composition major.

Thursday, September 08, 2005

Optimizing for scripting languages

Phlip on the The XP Yahoo! group writes a nice bit about Ruby v. Python (and along the way Perl). He references AlternateHardAndSoftLayers from the fabled C2 wiki in making a nice point about optimizing for scripting languages:

Dynamic languages and unit tests permit you to blaze through features and refactors. Without the requirement to maintain inheritance graphs just to substitute objects, and with deep support for containing objects and translating their types, these languages stay out of your way.

Command-and-control code does not require performance. Low-level inner loops do, so practitioners typically port to a C language as soon as parts slow down. This pattern (AlternateHardAndSoftLayers) allows Ruby and Python to ship with very powerful libraries, bundled with their default distributions.

This is excellent advice and another indication that the best programmers are also some of the most well-rounded. Being the world's greatest expert on FOO at the expense of knowing little else is not that useful outside of one-language/one-vendor closed shops.

Programmatically compiling Java in JDK 6

Build 47 (August 12th) of JDK 6 (Mustang) includes this improvement:

Category ID Synopsis
java:compiler 
  4164450 JSR 199: Standard interface for Java compilers

(Offhand, why is SUN's HTML for this page so bad? The source HTML is not even valid, let alone tasteful.)

The link is to this bug report; its heart:

This feature is for a standard interface that is available as a standard extension to Java. That way you have a richer way to access the compiler (if one is available) without forking a new process or relying on undocumented features. You also make it easy for the user to install a different compiler without breaking the tools that rely on it.

The Yahoo! group to discuss the feature makes it clear that this feature was originally intended for JDK 5 (Tiger) but pushed back to JDK 6 (Mustang), and that is as far as the group got. However, JDK 5 did expose com.sun.tools.javac.Main. However, the bug report says that JDK 6 addresses:

  • Programmatic API to invoke the compiler
  • API to access structured diagnostic information
  • API to override how the compiler reads and writes source and class files.

Progress!

The JDK 6 API docs do not show any obvious signs of this. So of to the sources (NB — this is the JRL download, not the SCSL). Comparing the two sources for com.sun.tools.javac.Main shows interesting changes. After building the javadocs for just this class, I can read some eye-catching improvements; the opening lines:

The programmatic interface for the Java Programming Language compiler, javac.

Except for the two methods compile(java.lang.String[]) compile(java.lang.String[],java.io.PrintWriter), nothing described in this source file is part of any supported API. If you write code that depends on this, you do so at your own risk. This code and its internal interfaces are subject to change or deletion without notice.

Some heavy caveats, but very promising! The documentation for main(java.lang.String[]) is amusing:

Unsupported command line interface.

The full method javadocs for this class are (after cleaning javadocs' peculiar HTML):

main

public static void main(java.lang.String[] args)
                 throws java.lang.Exception

Unsupported command line interface.

Parameters:
args - The command line parameters.
Throws:
java.lang.Exception

compile

public static int compile(java.lang.String[] args)

Programmatic interface to the Java Programming Language compiler, javac.

Parameters:
args - The command line arguments that would normally be passed to the javac program as described in the man page.
Returns:
an integer equivalent to the exit value from invoking javac, see the man page for details.

compile

public static int compile(java.lang.String[] args,
                          java.io.PrintWriter out)

Programmatic interface to the Java Programming Language compiler, javac.

Parameters:
args - The command line arguments that would normally be passed to the javac program as described in the man page.
out - PrintWriter to which the compiler's diagnostic output is directed.
Returns:
an integer equivalent to the exit value from invoking javac, see the man page for details.

Well, it's a start.

That cool FTP hack

As noted in several places, Avi Bryant thought up a very clever hack: having paths in an FTP server actually browse his Smalltalk image.

Cedric make the observation:

The article illustrates the challenge by creating a dynamic FTP server that exposes the internals of a Smalltalk application. Of course, it would be equally interesting to expose a Java application this way and browse the packages, classes and methods. You could also imagine creating a file system (/dev/java ?) that would let you create an object with touch and remove it with rm...

The next step is pretty clear. The FTP server should not just browse Java source, but should compile on upload with the upload failing if the compilation fails. Alternatively, the server would keep track of compiling and non-compiling code so that one could create and edit Java source files, but the system would distinguish between compiling and non-compiling sources. In either case downloads retrieve the original Java source (or are based on file extension).

Lastly, successful compilation of uploads would use class loader magic to affect the running system. One could then work on the live, running FTP server itself with GET, PUT and DELETE. Or, using any of the various FTP mount solutions, do the same work with cp, mv and rm as suggested by Cedric. Now that's a cool hack.

Wednesday, September 07, 2005

A common unit test error

Hani, in his usual unusual style (a warning to sensitive souls), points out a common unit test error:

So after a few days of pointlessly scrolling around, I find the culprit. It's at this point that I completely lose it and start laughing hysterically. I can't quite believe the test I'm looking at.

The test for http state works thusly: It gets at the class that holds the map. It uses reflection to access the (private) map, makes it accessible, and manually puts a value in it. Having done so, it then calls a method which basically just reads from the map, and then compares the two.

It's mind boggling to me that someone would write such a complex and awkward test to basically test that HashMap functions as a....map.

Simple solution: don't do this. There are several technical approaches superior to all the reflection described, but just don't bother to unit test the JDK.

Tuesday, September 06, 2005

JSF and AJAX

A delightful page on mixing JSF and AJAX. Particularly helpful is that the authors present three strategies—not just a simple HOWTO recipe—and a comparison among them. And the article is richly researched, a joy to read.

With the discussion of Sun open sourcing the JSF RI (reference implementation), this article deserves a wider audience.

Refactoring Thumbnails

What a wonderful resource! A set of simple descriptions and straight-forward UML diagrams for common refactorings. The link has been up on the refactoring web site for about a year now, but I somehow I missed it.

Take this example, Hide Implementation With Interface:

client code directly accesses features of an implementation class despite the presence of an interface   restrict the client code its use of features to those provided by the available interface

Monday, September 05, 2005

Drools

Drools, the Java rules engine, has been getting press lately. O'Reilly has a nice pair of articles, one with examples, the other a higher-level view.

A lot of Drools is based on work first done in CLIPS, the LISPy rules engine of the 80s and early 90s. Strangely, I already knew about CLIPS. They are all based around the Rete algorithm, a clever way to trade computation for memory with if-then-else rules systems.

I learned about CLIPS in the late 80s from Brian Donnell (now Dantes), a fine fellow. We were classmates together at in Baker College at Rice University, and in fact he was the very first person to ever explain Object Oriented Programming to me. (As he wrote COOL, the OOP system in CLIPS, this was a topic he enjoyed discussing.) He tried describing it in context of C with Classes and C++; at that time the only language I knew was C. I can thank him and Matt Cohen (who taught me C) for starting my life in programming.

So I am pleased to see systems like Drools and Jess getting some press. And still, LISP lives on.

Friday, September 02, 2005

Fun with Ant macros

Noticing that many Ant file operations were rather slow on large directory trees, I fell back to the tried and true: <exec/>. But I noticed that as I coded up cp, mv and rm, that the calls to <exec/> became rather tedious and repetitious. Looking around a bit, I found just the thing: <macrodef/>! First the starting code using rm as an example:

<echo message="rm -rf ${some.dir}"/>
<exec executable="rm">
    <arg value="-rf"/>
    <arg value="${some.dir}"/>
</exec>

Pretty straight-forward. Just note that <exec/> is silent so I add an <echo/>. This corresponds to the shell command:

$ rm -rf $some_dir

The next step is to turn this into a macro:

<macrodef name="rm">
    <attribute name="src"/>
    <sequential>
        <echo message="rm -rf @{src}"/>
        <exec executable="rm">
            <arg value="-rf"/>
            <arg value="@{src}"/>
        </exec>
    </sequential>
</macrodef>

Notice that the '$' became a '@' and the <exec/> is now wrapped in a <sequential/> tag. That is how Ant tells apart macro parameters from properties. With this change, I can now use this Ant script snippet:

<rm src="${some.dir}"/>

Much more readable!

Next I want to make this a bit more reusable. My example was super simple, but other cases might need to use some of the attributes for <exec/>. For my purposes, I added dir, spawn and failonerror. I found real uses of dir and failonerror in our codebase, and I wish to single out spawn in just a minute. That yields:

<macrodef name="rm">
    <attribute name="src"/>
    <attribute name="dir" default="."/>
    <attribute name="spawn" default="false"/>
    <attribute name="failonerror" default="false"/>
    <sequential>
        <echo message="rm -rf @{src}"/>
        <exec executable="rm" dir="@{dir}" spawn="@{spawn}"
                failonerror="@{failonerror}"
            <arg value="-rf"/>
            <arg value="@{src}"/>
        </exec>
    </sequential>
</macrodef>

Combined here are the techniques for macro attribute defaults and for passing down attributes for tasks wrapped in a macro. These serve well to preserve expected defaults and avoid surprises for macro users.

Aside: Why does failonerror default to false? This seems a perverse choice for a build system when fail-fast strategies save so much developer time in large projects.

Lastly, I want to make the macro generic to work with cp and mv, not just rm. So I did the obvious (to me) thing: I made a macro with the macro. Thus:

<macrodef name="file-operation">
    <attribute name="operation"/>
    <attribute name="message"/>
    <element name="attributes"/>
    <element name="args"/>
    <sequential>
        <macrodef name="@{operation}">
            <attributes/>
            <attribute name="dir" default="."/>
            <attribute name="spawn" default="false"/>
            <attribute name="failonerror" default="false"/>
            <sequential>
                <echo message="@{message}"/>
                <exec executable="@{operation}" dir="@{dir}"
                      spawn="@{spawn}" failonerror="@{failonerror}">
                    <args/>
                </exec>
            </sequential>
        </macrodef>
    </sequential>
</macrodef>

And my definition of the <rm/> macro becomes:

<file-operation operation="rm" message="rm -rf @{src}">
    <attributes>
        <attribute name="src"/>
    </attributes>
    <args>
        <arg value="-rf"/>
        <arg value="@{src}"/>
    </args>
</file-operation>

Usage stays the same:

<rm src="${some.dir}"/>

And likewise for cp and mv:

<file-operation operation="cp" message="cp -a @{src} @{dst}">
    <attributes>
        <attribute name="src"/>
        <attribute name="dst"/>
    </attributes>
    <args>
        <arg value="-a"/>
        <arg value="@{src}"/>
        <arg value="@{dst}"/>
    </args>
</file-operation>

<file-operation operation="mv" message="mv @{src} @{dst}">
    <attributes>
        <attribute name="src"/>
        <attribute name="dst"/>
    </attributes>
    <args>
        <arg value="@{src}"/>
        <arg value="@{dst}"/>
    </args>
</file-operation>

With corresponding Ant script calls:

<cp src="${some.dir}" dst="${dupliate.dir}"/>
<mv src="${some.dir}" dst="${renamed.dir}"/>

One last itch remains for me. The raison d’ĂȘtre I started down this road in the first place was to speed up <delete dir="${some.dir}"/>. An optimization I realized early on was not just to call to rm, but to run the operation in the background:

<tempfile property="tmp.dir" prefix=".tmp."/>
<mv src="${some.dir}" dst="${tmp.dir}"/>
<rm src="${tmp.dir}" spawn="true"/>

This pattern renames ${some.dir} to a random temporary directory and deletes the temporary directory in the background. The documentation of <exec/> even claims the operation continues after the Ant script exits. Perfect! Now to simplify usage of the pattern:

<macrodef name="rm-background">
    <attribute name="src"/>
    <attribute name="property"/>
    <attribute name="dir" default="."/>
    <attribute name="failonerror" default="false"/>
    <sequential>
        <tempfile property="@{property}" prefix=".@{property}."/>
        <mv src="@{src}" dst="${@{property}}" dir="@{dir}"
            failonerror="@{failonerror}"/>
        <rm src="${@{property}}" spawn="true" dir="@{dir}"
            failonerror="@{failonerror}"/>
    </sequential>
</macrodef>

Gives:

<rm-background src="${some.dir}" property="tmp.some.dir"/>

Notice that the temporary directory begins with a '.'. This is to make it hidden under UNIX/Cygwin so it doesn't clutter ls.

Time for a peanut butter sandwich.

UPDATE: I've saved everything in one place for easy examination.

Tuesday, August 30, 2005

Deleting things with Ant

One thing about Ant I have noticed is that file operations are slow and recursive operations are especially so. Consider this toy Ant script to delete a directory in the background while carrying on in the foreground:

<project name="parallel-delete" default="all">
    <property name="old.dir" value="build"/>
    <available file="${old.dir}" property="old.dir.exists"/>

    <target name="all" depends="rename-old-dir">
        <parallel>
            <apply executable="rm">
                <arg value="-rf"/>
                <dirset dir="." includes="${old.dir}.*"/>
            </apply>

            <sequential>
                <!-- Real work goes here -->
                <sleep seconds="1"/>
                <echo message="Snoozing..."/>
            </sequential>
        </parallel>
    </target>

    <target name="rename-old-dir" if="old.dir.exists">
        <tempfile property="tmp.dir" prefix="${old.dir}."/>
        <!-- Slow as all get out.
        <move todir="${tmp.dir}">
            <fileset dir="${old.dir}"/>
        </move> -->
        <!-- Deprecated, but works better than move.
        <rename src="${old.dir}" dest="${tmp.dir}"/> -->
        <!-- Fastest of all but only works on UNIX/Cygwin.
        <exec executable="mv">
            <arg value="${old.dir}"/>
            <arg value="${tmp.dir}"/>
        </exec>
    </target>
</project>

Notice the commented sections in the rename-old-dir target? Each of them has drawbacks. For my testing I setup with:

$ cp -a /usr/include build

This gave me a large directory tree to test with. You can decide from the comments which approach is least worst for you.

The actual technique—deleting in the background—is an interesting one and shaves considerable time off a large project wanting a clean rebuild. There is also the funny business with <apply/> also owing to Ant problems with file operations on a large, recursive tree. I cannot nest a <dirset/> element inside a <delete/> task (the <dirset/> type is, unfortunately, rather less useful than <fileset/>), but I need to delete directories, not files, and the name of the directory is a pattern. (I may have left over temporary directories to delete from previous, aborted runs.)

This solution is workable and fast, but with the drawback of targeting UNIX and Cygwin. Windows-only users get the short end of the development stick again.

My project is sitting on Ant 1.6.2; perhaps 1.6.3 addresses some of these. The syntax for file operations on directories is improving (e.g., <move file="src/dir" tofile="new/dir/to/move/to"/>) so some of my concerns may be already addressed.

More on the <parallel/> trick

My sample Ant script runs the cleanup in the background as foreground work continues. If the foreground work finishes, the script continues and the background completes. An alternative is to surround the background work with <daemons/>; then if the foreground finishes the script exits leaving the background work incomplete. For a cleanup task this isn't a terrible choice and one could have a vacuum process or task for removing detritus from previous incomplete background work with the benefit of having the Ant script finish faster.

UPDATE: Food for thought: here is a similar build script with make instead of Ant:

build.dir = build

all:
        : Do your work here
        sleep 1
        echo Snoozing...

rebuild: clean all

clean:
        test -d $(build.dir) && mv $(build.dir) $(build.dir).$$$$ || true
        ($(RM) -rf $(build.dir).* &)

Monday, August 29, 2005

Nice Ant 1.6.3 improvement for default values

Apache Ant 1.6.3 added a nice feature to the condition task. There is now an else attribute. The niceness is best illustrated by example:

<property environment="env"/>

<!-- The old, pre-1.6.3 way:-->
<condition property="foo.bar" value="${env.FOO_BAR}">
    <isset property="env.FOO_BAR"/>
</condition>
<condition property="foo.bar" value="Lives somewhere else">
    <not>
        <isset property="env.FOO_BAR"/>
    </not>
</condition>

And with Ant 1.6.3:

<property environment="env"/>

<!-- The new, 1.6.3 way:-->
<condition property="foo.bar" value="${env.FOO_BAR}"
        else="Lives somewhere else">
    <isset property="env.FOO_BAR"/>
</condition>

It could be more concise still, but this is an improvement.

Wednesday, August 24, 2005

Saturday, August 20, 2005

A home page

I enjoy posting code snippets but sometimes a full project is more helpful. On my home page are several links to downloads for several of my more interesting (to me) posts. Cheers!

Friday, August 19, 2005

GNU autotools lessons learned

Along the way to autoconfiscating portions of our Windows to Linux port for my company's desktop softare, I discovered the autoreconf gem. It handles most of what I had stuffed into a autogen.sh script.

One nit. I have some custom macros in an m4/ subdirectory which add support for --enable-debug, --enable-profile and --enable-release flags to ./configure. (Why aren't these standard, or at least the macros standard?) autoreconf supports an -I m4 option to pass these to autoconf and autoheader, but not to aclocal.

Drat!

However, thanks to GNU Automake by Example, I found that I can put a ACLOCAL_AMFLAGS = -I m4 line in the top-level Makefile.am to pass -I m4 to aclocal. This is an unfortunate code duplication, but better than simply having the feature broken.

I also discovered autoupdate which brought my configure.ac file up to current standards. Nifty.

Lastly, I saw that autoreconf is actually quite clever. If I have never run ./configure, the --make option does nothing as it does not know how I wish to configure the project (the install directory, for example). However once I have run ./configure, autoreconf reuses the settings from that first run for subsequent runs of ./configure and then dashes off with make afterwards.

Thursday, August 11, 2005

Teaching configure about build flags

Cobbled together from several sources around the Internet, I put together a solution this morning to a question posed by one of our developers: how do you make debug v release builds with GNU autotools?

A first pass at answering produced the ac_build_types.m4 macro for autoconf. First, some usage. Here is configure.ac:

AC_PREREQ(2.59)
AC_INIT([my_project], [0.0.0], [binkley@alumni.rice.edu])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE

AC_BUILD_TYPES

dnl Rest of file...

The only thing different from a standard configure.ac is the addition of AC_BUILD_TYPES. The effect of that shows in ./configure:

$ ./configure --help
# ...
Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --enable-debug          build debug version
  --enable-profile        build profiling version
  --enable-release        build release version
# ...

Now there are flags to build debug, profiling and release builds.

Last is the macro itself:

C_DEFUN([AC_BUILD_TYPES],
[
AC_ARG_ENABLE(debug,
      [  --enable-debug          build debug version],
      CFLAGS="$CFLAGS -DDEBUG -O0 -g3 -Wall"
      CXXFLAGS="$CXXFLAGS -DDEBUG -O0 -g3 -Wall")
AC_ARG_ENABLE(gprof,
      [  --enable-profile        build profiling version],
      CFLAGS="$CFLAGS -pg"
      CXXFLAGS="$CXXFLAGS -pg"
      LDFLAGS="$LDFLAGS -pg")
AC_ARG_ENABLE(release,
      [  --enable-release        build release version],
      CFLAGS="$CFLAGS -DNDEBUG -g0 -O3"
      CXXFLAGS="$CXXFLAGS -DNDEBUG -g0 -O3")
])

That's all! Save the definition into something like ac_build_types.m4 and run aclocal -Idirectory-containing-macros as part of creating your ./configure for other developers.

Wednesday, August 10, 2005

Almost there

As part of exploring a Windows to Linux port, I looked into generating Windows DLLs with automake and libtool. After some experimenting, I have almost everything I want in an example library, Foo:

  1. Builds static and shared libraries for Linux
  2. Builds static and shared libraries for Windows
  3. Windows libraries can depend on Cygwin
  4. Windows libraries can be entirely independent of Cygwin

Here's how I build for that last case:

$ ./autogen.sh
$ CC="cc -mno-cywin" CXX="cc -mno-cygwin" LTCC="cc" ./configure --prefix=/tmp/foo
$ make install

This installs everything under /tmp/foo (where I can easily clean up between test runs).

Why LTCC="cc"? It turns out that libtool writes a temporary wrapper for the main and just this temporary wrapper needs the full Cygwin environment. Libtool provides LTCC for building the wrapper independently of CC used for everything else. Without the extra setting, everything actually works but produces spurious errors during building. (If you want an explanation of -mno-cygwin, see the manpage for GCC under Cygwin.)

I posted this under the title Almost there. There is one more detail to work out. Even though the DLL has no Cygwin depedencies, it is still named cygfoo-0-0-0.dll rather than foo.dll as expected. Everythings works correctly, but this is annoying. You cannot rename the DLL either as this breaks loading for programs linked against it. When I figure this last bit out, I'll post an update to this entry.

Runtime traces for C

While porting some software from Windows to Linux, I needed to see backtraces. If there is no global exception handler and an exception in C++ is not caught, it aborts the program. The reports I got went along the lines of some program output:

$ run_foo
Aborted.

Not very helpful!

So I wrote a small pair of trace macros based on the GNU C Library's backtrace facility. Although this facility is only available for UNIX and Linux platforms, my tracing macros still are helpful under Windows sans backtracing.

#ifndef TRACE_H_
#define TRACE_H_

#include <stdio.h>
#include <stdlib.h>

#define TRACE_BACKTRACE_FRAMES 10

#ifdef __GNUC__
# define __FUNCTION__ __PRETTY_FUNCTION__
#endif

/* Emacs-style output */
#ifdef EMACS
# define TRACE_PREFIX   fprintf (stderr, "%s:%d:%s", __FILE__, __LINE__, __FUNCTION__)
#else
# define TRACE_PREFIX   fprintf (stderr, "%s(%d):%s", __FILE__, __LINE__, __FUNCTION__)
#endif /* EMACS */

#ifdef linux
# include <execinfo.h>

# define TRACE_DUMP()   do {     void *array[TRACE_BACKTRACE_FRAMES];     int n = backtrace (array, sizeof (array) / sizeof (void *));     char **symbols = backtrace_symbols (array, n);     int i;      for (i = 0; i < n; ++i)       fprintf (stderr, " -[%d]%s\n", i, symbols[i]);      free (symbols);   } while (0)
#else
# define TRACE_DUMP()
#endif /* linux */

#define TRACE()   TRACE_PREFIX; fprintf (stderr, "\n");   TRACE_DUMP ()

#define TRACE_MSG(MSG)   TRACE_PREFIX; fprintf (stderr, ": %s\n", MSG);   TRACE_DUMP ()

#endif /* TRACE_H_ */

Use the EMACS define to switch between Emacs-style and regular line tracing.

UPDATE: I meant to provide sample output:

trace.c(9):bob: Some interesting debug message.
 -[0]./trace(bob+0x51) [0x804878d]
 -[1]./trace(main+0x21) [0x8048817]
 -[2]/lib/tls/libc.so.6(__libc_start_main+0xd0) [0x4021de80]
 -[3]./trace [0x80486a1]

One thing jumps out immediately: this is not Java. But one can tease out that main called bob and bob wrote a trace message. Notice this:

trace.c(9):bob: Some interesting debug message.
 -[0]./trace(main+0x51) [0x8048841]
 -[1]/lib/tls/libc.so.6(__libc_start_main+0xd0) [0x4021de80]
 -[2]./trace [0x80486a1]

That is the same output with -O3 passed to GCC. The compiler inlines away the trivial bob function. -O2 did not inline the function.

Friday, July 29, 2005

The complexity of Map in Java

I just posted an updated version of my util library of extensions to Java Collections in the course of which I added a ListMap interface to replace UnionMap and an implementation, ArrayHashListMap.

If one were to write read-only Map implementations, the procedure is straight-forward and well-documented in the Javadocs for Map. However, writing a modifiable map is much more of an undertaking.

Consider all the places that "modifiability" can be leaked:

entrySet()
This is burdensome as the Set has to provide modifiable operations which effect the original Map and all methods of Set which themselves return modifiable collections or iterators need to tie back to the original Map all the way down to Map.Entry.
keySet()
The same remarks for entrySet() apply to keySet() (exception Map.Entry).
values()
Similarly for values() although it is a Collection rather than a Set, a distinction of very little.
layers()
A method particular to ListMap, it returns a list of maps which comprise the PATH-like layers which are collapsed to present a single Map view.

What did I do in face of this? I introduced a new interface, Refreshing (would Refreshable have been better?), which has one method, void refresh(), implemented versions of Map List, Set and Iterator which take a Refreshing object to signal after modifiable operations complete, and extended AbstractMap to return refreshing versions of collection classes for each of the possible points where modifiability leaks. You can see the result in ListMap and ArrayHashListMap.

Thank goodness for mock objects and unit tests!

Tuesday, July 26, 2005

More automake, now with packages

Murray Cumming had a lot of helpful things to say about automake and libraries. Drawing from that, I found the right way to package our inhouse libraries for reuse was to add this to the library's Makefile.am:

pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = name_of_library_project.pc

And drop a name_of_library_project.pc.in into the top-level library project directory:

prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@

Name: Name of library project
Description: Some description here.
Requires:
Version: @VERSION@
Libs: -L${libdir} -lname_of_library link list of libraries for this project
Cflags:

The rest was magic, and "just worked". To other projects wanting to use the library, add this to their configure.in (or configure.ac; different names, same files):

PKG_CHECK_MODULES(DEPS, name_of_library_project)
AC_SUBST(DEPS_CFLAGS)
AC_SUBST(DEPS_LIBS)

(See my earlier post on autogen.sh.)

Monday, July 25, 2005

Porting the Angband borg to 3.0.6

The very excellent APWBorg for Angband does not compile out of the box for version 3.0.6, but the fix is simple. Make these substitutions in the borg?.c file:

Term->offset_x for p_ptr->wx
Term->offset_y for p_ptr->wy

This matches the ChangeLog description:

2004-05-31 17:26  rr9

        * src/: cave.c, cmd3.c, defines.h, dungeon.c, files.c, generate.c,
        l-player.pkg, spells2.c, types.h, wizard2.c, xtra2.c: Replaced the
        'wx' and 'wy' main term viewport coordinates with window specific
        offsets.

A simple diff of src/cave.c between versions 3.0.5 and 3.0.6 shows this change in the mainline sources.

UPDATE: Some tips on installing APWBorg under Linux in the form of command history:

$ unzip 305Borg.zip
$ cd 305Borg
$ rm MAIN-WIN.C
$ for x in *
> do mv $x $(echo $x | tr '[:upper:]' '[:lower:]')
> done
$ dos2unix *
$ ANGBAND=... # where ever you unpacked angband-3.0.6.tar.gz
$ cp borg*.[ch] $ANGBAND/src
$ cp borg.txt $ANGBAND/lib/user

You still need to fix up the make process to compile and link the borg sources into angband. Copy the sample autogen.sh to $ANGBAND and chmod +rx autogen.sh. Add the nine borg?.c files to the list of sources in $ANGBAND/src/Makefile.am. Add borg.txt to the list of sources in $ANGBAND/lib/user/Makefile.am. Then:

$ cd $ANGBAND
$ ./autogen.sh
$ ./configure --prefix=$ANGBAND
$ make install

Now play angband.

UPDATE: I dropped Dr. White a line and got a reply. Looks like my patch will make it into the next version of his borg. Yah for open source!

Sunday, July 24, 2005

ReverseList for Java

One of my Java pastimes is writing trivial utility classes. Part of my interest is stylistic: I hate seeing blocky, chunky code that could be replaced by elegant, simple code. Illustrating my point, I needed a reversed list which presented an underlying list in reverse order. So I created a simple utility class, ReverseList, which fits the bill:

class ReverseList<E>
        extends AbstractList<E> {
    private final List<E> list;

    public ReverseList(final List<E> list) {
        this.list = list;
    }

    public void add(final int index, final E element) {
        list.add(reverseIndex(index) + 1, element);
    }

    public E remove(final int index) {
        return list.remove(reverseIndex(index));
    }

    public E get(final int index) {
        return list.get(reverseIndex(index));
    }

    public E set(final int index, final E element) {
        return list.set(reverseIndex(index), element);
    }

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

    private int reverseIndex(final int index) {
        return size() - index - 1;
    }
}

The only trick to it is to note that add(int, Object) requires one bump the reversed index. I only discovered this during unit testing and was puzzled for a while. Then I realized that add is conceptually akin to inserting in that it shifts elements to the right: reversing the list shifts to the left, hence, requires that indices be off by one.

UPDATE: An even better explanation for the index in add: The indices are akin to point in Emacs, that is, they note the spot between elements and are just to the left of a given element. If you think of elements as boxes in a row, the point is the gap to the left of a box between it and the box next to it.

Reversing a list is like reflecting it in a mirror: traversing it from beginning to end becomes end to beginning when reversing. Likewise, point is reflected from being just to the left of an element to just to the right of an element. To represent this change in the original, underlying list is to increase the index of point by one.

UPDATE: Andrew McCormick pointed out that "reverse list" also has another name: Stack.

Friday, July 22, 2005

Java's weakness, C++'s strength

For the most part I enjoy coding in Java more than in C++. Especially with tools like the Intellij IDEA refactoring editor, my productivity is higher in Java and my pain lower. However, the one thing from C++ I miss the most is the destructor.

Strangely, many C++ programmers (at least those I witness) seem to overlook this strength. One of my favorite utility classes is so simple:

#include <stdio.h>

class auto_file {
  FILE* filep;

public:
  auto_file (const char *path, const char *mode) {
    if (!(filep = open (path, mode))
      throw some_program_specific_exception (path, mode);
  }

  ~auto_file () { close (filep); }

  operator FILE* () { return filep; }
};

Most times I could just use <fstream>, but sometimes I need to pass around file descriptors or FILE pointers to code outside my control. And when you work with sockets (which need the same treatment), there is no standard library facility.

Java's try-finally approach to releasing system resources is ok for many uses, but is prone to forgetfulness and does not work at all when object scope is complex.

The one thing I miss most in Java is the destructor. It would be swell to introduce a new language facility for them (something different from the finalize() fiasco). With garbage collection, Java could do an even better job than C++.