A beginners guide to Ant

steve loughran 2001-04-30

 

Introduction

This is a quick introductory tutorial to the Ant build tool. It is intended for people starting out with Ant and Java development, and aims to provide enough detail to get started. It does not attempt to replace the core and documentation, merely extend it. Nor does it cover advanced ant use -see the sister document 'ant in anger' for that.

Important: the author flatly refuses to answer any email related to this tutorial. You have any questions? Post them to the ant-users mailing list where you will get an answer.

Before you Begin

Are you sitting comfortably? Then we'll begin. To start using ant you will need the following
  1. A computer with a recent Java runtime -1.3 preferred, 1.2.2 works in a push. If you are still using java 1.1, and not stuck with it because you are doing some embedded system -upgrade now!
  2. A Java SDK to match the runtime. Installed with the environment variable JAVA_HOME set to point to it.
  3. Some kind of text editor. A great editor for java application development is Jedit.
  4. The Ant jar and required libraries downloaded to the computer. Fetch the latest milestone release..
  5. Ant configured to run when you type "ant" at a command window. This requires the path and ANT_HOME to be precofigured, as described in the main ant manual..
There is a simple test to see if all this has been done. Create a new command window/shell window and type in 'ant'-you should see something like this:-
C:\>ant
Buildfile: build.xml does not exist!
Build failed
Almost anything else and you have missed out at least one of the steps above. The 'almost' is that if through some quirk of fate there is a build.xml file in that directory then you may have actually gone and built something. oops.

The story of Ant

Once upon a time, way back when you had to rewrite applications to run on different operating systems, and recompile applications to run on different processors, the whole tasks of "managing the build" was such a complex operation that large projects had people working on the task full time. Their primary tool was 'make', a powerful tool which could mix inference rules (what commands to issue to produce a .o object file from a .c C source file), with explicit dependencies:-
#makefile example


main: app.exe


app.exe: core.obj extras.obj
	#linking commands
	link /o app.exe core.obj extras.obj


core_headers: core.h platform.h


core.c: core_headers


extras.c: core_headers extras.h


.c.obj:
	#rule to compile a c file using a magic variable 
	cc -c $@
To anyone experienced in makefiles this is a simple C project with two source files (core.c and extras.c), each dependent upon some header files, a compilation rule stated at the bottom and some linker used to link the files together.

Note that that is a simple make file. A complex one is -well- complex. A cross platform one is even more complex, as the commands to perform various tasks vary from system to system. That is why imake came in to being -a program which generates the appropriate makefile for a platform by actually trying out the software installed on the system to see what works and what does, then generating a platform specific makefile. Cross platform development was never fun, especially when testing came in to the equation.

Java changed the whole notion of cross platform software. Now you could run a program on many different operating systems and microprocessors. But for a long time the actual development process lagged. You could stick with make -and require everyone to develop on the same platform, or use an IDE -and require everyone to use the same IDE. These were viable options in small team projects, but not in the open source world.

Ant changed the whole notion of cross platform software development. The funny thing is -this was almost (but not entirely) by accident.

This story needs to be clarified and verified, but it should be preserved for posterity

When Sun donated the reference JSP/servlet code to the Apache project, for incorporation into the Tomcat web server, one of the things that came with it was Ant. This was some code that James Duncan Davidson wrote to provide Tomcat with a simple build process on any java platform. Although it was simple, it was designed with extensibility in mind - extensibility through Java based add in tasks, not through ever more complex makefile like scripts.

Because it was platform agnostic, because it made the java build process easy and (perhaps) because it was free, it soon started being used by many java development projects. The usual rule was 'you can use any IDE you like to code and debug, but ant is the build tool'. With increased poularity many more extension tasks were added to ant, aiding deployment, database integration, email and sound notification of build completion. Thus it became the complex and powerful build tool it is today.

Lesson 1: Your first Ant build

Files for this lesson

Step 1: source file

Before you can actually build a program with Ant, you need some code to compile. So, here is a short program to do almost nothing, perhaps part of a grand library of binary functions.


/* lesson 1 file */
import java.io;
public class Adder {

    int _data=0;

    public Adder(int data) {
        _data=data;
    }

    public int execute(int parameter) {
        return parameter;
    }

    public String toString() {
        return "Adder "+_data;
    }

    public int getValue() {
        return _data;
    }

    static void main(String args[]) {
        Adder plus=new Adder(4);
        System.out.println(plus.toString());
        int arg=2;
        int result=plus.execute(arg);
        System.out.println(plus.getValue()+" + "+arg+" = "+result);
    }
}

Cut the code out and save it to the file Adder.java, being careful to get the case of the source file perfect.

You now have a file to compile. There is no guarantee it will compile reliably, or indeed work -but that makes it like any other source you write. The development process is about testing, fixing and feature creep. In fact, anyone who looks at the code closely will see that there is indeed a bug in the code. Don't worry about that -it will get fixed later.

Step 2: the build file

To get ant to build a file, you have to tell it what you want to do. That is done with an ant build file, a file usually called "build.xml".


<?xml version="1.0"?>
<!-- build file for lesson 1 -->

<project name="tutorial" default="build" basedir=".">
    <target name="build">
        <javac srcdir="." />
    </target>
</project>

Lets run the file:

>ant
Buildfile: build.xml

build:
    [javac] Compiling 1 source file

BUILD SUCCESSFUL

Total time: 3 seconds

The success message tells us that the build worked, now lets see what got produced

>java Adder
Adder 4
4 + 2 = 2

So, clearly the build worked, even if the program is hopelessly broken.

Now, what, did that build file say?

The first line - <?xml version="1.0"?> tells us that this is an xml file. The xml extension kind of gave that away, but this just makes it clear. XML aficionados will be scanning down looking for a DTD or XSD definition describing what subset of valid XML is permitted. Ant does not need one, or a validating parser.

An ant build file is an XML file

The second line: <!-- build file for lesson 1 --> is just an XML comment. It is very prudent to document the file for future reference.

The next line is where it gets interesting: <project name="tutorial" default="build" basedir="."> .This states that this xml file contains an ant project, with the default target called "build", and the base directory of ".", which of course means "this directory". Being proper XML, the project clause is closed with a </project> statement a few lines down.

An ant build file contains one project

Inside the project element is the <target name="build"> statement. There can be an arbitrary number of targets inside a project, each one performing a different part of the build process. When you invoke ant you can either explicitly name the target(s) you want to build, or use the default target named in the project line. As there is only one target in this project, it makes no difference.

A project contains one or more targets

Inside the target is the one step needed to build this target: <javac srcdir="." /> . This tells ant that this target is built by calling the javac task in the current directory. An 'ant task' is simply a java class in the ant jar or another jar in the ant classpath. Somehow ant knows that when it sees the element 'javac' inside a target that it should pass all the parameters provided to an instance of the org.apache.tools.ant.taskdefs.Javac class, which goes on to build all the java files in the current directory.

An ant target contains zero or more task declarations

An ant declarations contains the information the task implementation needs to perform that stage of the build process. Task implementations are (usually) java classes included in ant.jar

And that is all there is to building simple java programs in ant. So if that is all you want to do for now, the class is adjourned.

Lesson 2: A few extra options

Files for this lesson

It seems really strange that the java compiler doesn't bother to ask any questions at all about what you want to build, such as which files to compile, or what debug options you want. It has some built in defaults, but if you run ant in verbose mode ("ant -verbose") you will see among part of the log that javac is actually looking at all files in the current directory. So it's time to override some of the defaults in a new build.xml


<?xml version="1.0"?>
<!-- build file for lesson 2 -->

<project name="tutorial" default="build" basedir=".">
    <target name="build" >
        <javac srcdir="."
            debug="true"
           optimize="false"
            includes="**/*.java"
            />
    </target>
</project>

This build file explicitly states what the debug and optimise options are, and then states that the task should act on all java files in this directory and all subdirectories. That is done by the includes="**/*.java" line. If you look at the documentation for the javac task then you will see that the includes tag takes a comma separated list of files to include. Ant's special handling of wildcards expands **/ to any number of directories, while its special handling of file separators means that '/' works as a directory separator, even on DOS descended operating systems. Equally, ant will let you use a backslash file separator '\' on a unix box.

ant tries to make it easy to write build files which build on any platform

In ant you don't usually need to worry about which way directory separators go, -'/' or '\', it gets sorted out.

ant tries to make it easy to write build files which build on any platform

The reason ant buildfiles are so simple is that the tasks do much more of the work. It is the javac task which picks the classes to build and generates the appropriate command syntax for the java compiler you can use -the task supports the Symantec, Microsoft and IBM jikes compilers too, see. All those details are hidden, unless you want to see what is going on by typing 'ant -verbose'.

Dependent Tasks

( an init task to create an output dir, param on javac to spit the classfiles to the build dir; a clean task using -projecthelp how to set defaults )

ant builds a graph of targets to perform, then executes them

users can name which target(s) to build, or let ant work it out itself

Properties

(How to assign properties. example will be release and debug options for the build)

ant properties can be explicitly set or loaded from a file

properties are immutable -once one is defined in a preceeding task, it can never change

Testing Tasks

(junit class added to test our adder.java, and build.xml extensions. Will of course catch the obvious bug)

Junit is a simple yet powerful unit testing framework.

Ant lets you integrate junit testing with the build process

With an integrated build and test process you are ready to live the XP development lifecycle, so run out and buy copies of 'XP' installed and 'Refactoring'.

Deployment Tasks

So, you can build, you can test. One thing left: ship. Ok, there's documentation too, but we'll ignore that.

deployment is all those bundling up and delivery activities that IDEs neglect. Ant is good at these.

Copy to make the dist image

Zip, Jar, WAR, Ear, tar: the build tasks

The Archive tasks (zip, jar, tar) and the special derivatives (War and Ear) exist to make deployable bundles from your code

The ftp and copy tasks exist to deploy them.

 

More Advanced Stuff

Paths

Filesets

Adding in new Tasks

 

Summary and Wrap up

Ant marks another step in the evolution of build processes, one designed to work with today's tools and meet today's problems -java compilation, testing and deployment. It has its weaknesses, but for a certain set of problems it can become an essential part of the build process.

Copywright (c) 2001 Apache Project, all rights reserved.

 

[contact ] [copyright ] [software ]