Archive

Archive for August, 2008

Ant can be less verbose than Java

5 August 2008 Leave a comment

I had one of those rare opportunities today when I got to pair with one of the developers on our project. The story he’s working on has to do with generating usage documentation for a webservice at runtime. What he wanted was a list of source files to be available at runtime. The solution he came up with (which does work) was the following Java program:

package com.example.service.utils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

public class ListControllers {
    public static void main(String[] args) throws IOException {
        String outputFile = args[0];
        String srcDir = args[1];
        File f = new File(srcDir);
        File serverDir = new File(f, "com/example/service/server");
        String[] entries = serverDir.list();
        Arrays.sort(entries);
        BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile, false));
        for(String entry : entries) {
            if(entry.endsWith("Controller.java")) {
                writer.write(name + "\n");
            }
        }
        writer.flush();
        writer.close();
    }
}

This was then called by the following Ant snippet:

<mkdir dir="${target.dir}/war/WEB-INF/classes"/>
<java classname="com.example.service.utils.ListControllers" 
      classpath="${main.jar}" failonerror="true">
    <arg value="${target.dir}/war/WEB-INF/classes/controller.list"/>
    <arg value="${src.dir}"/>
</java>

This was then bundled up in the war file so that he could get his mits on it at runtime. It works, but is not without problems. My primary complaint is that it makes the build harder to understand. To figure out what’s going you need to find and open up the .java file, and be able to understand Java in the first place.

After a few minutes of pairing we managed to fix it with the following Ant snippet:

<mkdir dir="${target.dir}/war/WEB-INF/classes"/>
<pathconvert property="controller.list.propery" 
             pathsep="${line.separator}">
    <sort>
        <path>
            <fileset dir="${src.dir}/com/example/service/server" 
                     includes="*Controller.java"/>
        </path>
    </sort>
    <map from="${src.dir}/com/example/service/server/" to=""/>
</pathconvert>
<echo message="${controller.list.propery}" 
    file="${target.dir}/war/WEB-INF/classes/controller.list"/>

Not only is it now easy to see what we’re trying to do in the build file, but we managed to replace 29 lines of Java + Ant with 10 lines of Ant. Sweet!

Categories: Build, Development, Software