Ant Hello World Revisited

We’ll continue our Ant tutorials with “Hello World,” only now we’ll execute a Java class. Start by creating a simple hello class as shown below.

1
2
3
4
5
6
public class hello {
public static void main( String[] args )
{

System.out.println( "Hello World" );
}
}

From the command line, compiling, jarring and executing this class is as simple as:

1
$ javac hello.java
$ jar -cvf hello.jar hello.class
added manifest
adding: hello.class(in = 415) (out= 285)deflated 31%)
$ java -classpath hello.jar hello
Hello World

Now let’s write an Ant build file to compile. Naturally, you should start by reading the fine manual description of the javac task. We’ll just use the srcdir attribute to compile all java files in the directory tree rooted at srcdir.

1
2
3
4
5
6
<project default="compile">
<target name="compile">
<javac srcdir="." />
</target>

</project>

Executing ant from the command line:

1
$ rm *.class
$ ant -f hello.xml compile
Buildfile: hello.xml

compile:
    [javac] Compiling 1 source file

BUILD SUCCESSFUL
Total time: 4 seconds

Now, let’s add a target to create the jar. The destfile attribute is required and both the basedir and the includes attributes are necessary in this case. The jar file will only contain the manifest file without the basedir attribute and the includes attribute is required to exclude all the non-class files (in particular, the jar file cannot contain itself). The regular expression used in the includes attribute will match all class files in the directory tree rooted at basedir.

1
2
3
4
5
6
7
8
9
10
11
12
<project default="compile">
<target name="compile">
<javac srcdir="." />
</target>

<target name="jar" depends="compile">
<jar destfile="hello.jar"
basedir="."
includes="**/*.class"
/>

</target>
</project>

Executing ant from the command line:

1
$ rm *.jar
$ ant -f hello.xml jar
Buildfile: hello.xml

compile:

jar:
      [jar] Building jar: /Tutorial/Ant/Jar/hello.jar

BUILD SUCCESSFUL
Total time: 2 seconds
$ jar -tvf hello.jar
jar -tvf hello.jar
     0 Wed Jan 22 17:06:32 EST 2003 META-INF/
    55 Wed Jan 22 17:06:32 EST 2003 META-INF/MANIFEST.MF
   335 Wed Jan 22 16:36:16 EST 2003 hello.class

Finally, let’s add a target to execute our class. We insure that the jar is always built first by having the execution target run depend upon the jar target. In this example, both the classname and the classpath attributes of the java task are used to completely specify the class to execute – eliminating a dependence upon the CLASSPATH environment variable. And we request a new JVM by setting fork=”true”; providing the class full access to the java runtime and preventing a call to System.exit() from terminating the ant process.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<project default="compile">
<target name="compile">
<javac srcdir="." />
</target>

<target name="jar" depends="compile">
<jar destfile="hello.jar"
basedir="."
includes="**/*.class"
/>

</target>

<target name="run" depends="jar">
<java classname="hello"
classpath="hello.jar"
fork="true"
/>

</target>
</project>

And execute:

1
$ant -f hello.xml run
Buildfile: hello.xml

compile:

jar:

run:
     [java] Hello World

BUILD SUCCESSFUL
Total time: 2 seconds

25 June: Made the run target depend upon the jar target.
5 Oct 08: Building an executable jar with Ant.

Disclaimer: I don’t claim to be an expert on ant. Please send comments and corrections.