Creating a Build File from Sratch using Ant Script

Introduction:

This is an introductory tutorial to the Ant build tool, a free tool under GNU License and is available at http://jakarta.apache.org/ant/. Ant allows the developer to automate the repeated process involved in the development of J2EE application. Developers can easily write the script to automate the build process like compilation, archiving and deployment. It is intended for people starting out with Ant and Java development, and aims to provide enough detail to get started.

What is Ant?

Ant is a platform-independent scripting tool that lets you construct your build scripts in much the same fashion as the “make” tool in C or C++. You can use a large number of built-in tasks in Ant without any customization. Some of the most important tasks and related commands are built in the Ant distribution.

Ant               – Used to execute another ant process from within the current one.

Copydir         – Used to copy an entire directory.

Copyfile         – Used to copy a single file.

Cvs              – Handles packages/modules retrieved from a CVS repository.

Delete          – Deletes either a single file or all files in a specified directory and its sub-directories.

Deltree          – Deletes a directory with all its files and subdirectories.

Exec             – Executes a system command. When the os attribute is specified, then the command is only executed when Ant is run on one of the specified operating systems.

Get               – Gets a file from an URL.

Jar               – Jars a set of files.

Java             – Executes a Java class within the running (Ant) VM or forks another VM if specified.

Javac            – Compiles a source tree within the running (Ant) VM.

Javadoc/Javadoc2 – Generates code documentation using the javadoc tool.

Mkdir            – Makes a directory.

Property        – Sets a property (by name and value), or set of properties (from file or resource) in the project.

Rmic             – Runs the rmic compiler for a certain class.

Tstamp         – Sets the DSTAMP, TSTAMP, and TODAY properties in the current project.

Style            – Processes a set of documents via XSLT.
Ant’s build files are written in XML. Each build file contains one project and at least one (default) target. Targets contain task elements. Each task element of the build file can have an id attribute and can later be referred to by the value supplied to this. The value has to be unique

Components to run Ant:

JDK- A Java SDK to match the runtime. Installed with the environment variable JAVA_HOME set to point to it.

XML parser – In many cases, the XML parser is part of the lib files distributed with the Servlet runner or the Web Server. If not, the free XML parser is available from java.sun.com

Ant – The Ant jar and required libraries downloaded from http://jakarta.apache.org/ant/

Installing Ant:

Installation consists of downloading the files, adding the class libraries to the classpath, and adding the Ant binaries to the path.

Set the class path to the bin directory of the ant.

Let’s assume that Ant is installed in c:\ant\. The following code has to be put into autoexec.bat file:

set ANT_HOME=c:\ant
set JAVA_HOME=c:\jdk1.3
set PATH=%PATH%;%ANT_HOME%\bin

Testing Ant:

Go to command prompt and issue the following command.

C:\ant>Ant

Buildfile: build.xml does not exist! Build failed

C:\ant>

If this is installed correctly Ant will give the above message. Now its time to do some work with Ant that uses configuration file called build.xml. This is the file where you define the process of compiling, building and deploying.


Writing a build.xml file:

<?xml version=”1.0″?>

<!– Build file for our first application –>

<project name=”simpleCompile” default=”deploy” basedir=”.”>
<target>
<property value=”src”/ >
<property value=”classes” />
<property value=”/web/deploy/jsp” />
<property name=”deployProperties” value=”/web/deploy/conf” />
</target>

<target depends=”init”>
<deltree dir=”${outputDir}” />
</target>

<target depends=”clean”>
<mkdir dir=”${outputDir}” />
</target>

<target depends=”prepare”>
<javac srcdir=”${sourceDir}” destdir=”${outputDir}” />
</target>

<target depends=”compile,init”>
<copydir src=”${jsp}” dest=”${deployJSP}”/>
<copyfile src=”server.properties” dest=”${deployProperties}”/>
</target>
</project>

In the above code, First line of the build.xml file represents the document type declaration.  Next line is comment entry and the next line contains information about the overall project that is to be built.

<project name=”simpleCompile” default=”deploy” basedir=”.”>

The most important elements of the project line are the default and the basedir. The default attribute references the default target that is to be executed. Because Ant is a command-line build tool, it is possible to execute only a subset of the target steps in the Ant file.

For example, I could perform the following command:

% ant -buildfile simple.xml init

That will execute the ant command and run through the build.xml file until the init target is reached. So, in this example, the default is deploy. The Ant process invoked in the following line will run through the build.xml file until the deploy command is reached:

% ant -buildfile simple.xml

The basedir attribute is fairly self-explanatory as it is the base directory from which the relative references contained in the build file are retrieved. Each project can have only one basedir attribute so you can choose to either include the fully qualified directory location or break the large project file into smaller project files with different basedir attributes.

The next line of interest is the target line. Two different versions are shown here:

<target>
<target depends=”init”>

The target element contains four attributes: name, if, unless, and depends. Ant requires the name attribute, but the other three attributes are optional.

Using depends, you can stack the Ant tasks so that a dependent task is not initiated until the task that it depends on is completed. In the above example, the clean task will not start until the init task has completed. The depends attribute may also contain a list of comma-separated values indicating several tasks that the task in discussion depends on.

if and unless commands let you specify commands that are to be performed either if a certain property is set or unless that property is set. if will execute when the property value is set, and the unless will execute if the value is not set. You can use the available command to set those properties as shown in a following example, or you can set them via the command line.

The init target from the simple example contains four lines of property commands as shown here:

<property name=”sourceDir” value=”src” />

These property lines let you specify commonly used directories or files. A property is a simple name value pair that allows you to refer to the directory or file as a logical entity rather than a physical one.

If you wanted to reference the sourceDir variable later in the Ant file, you could simply use the following syntax to alert Ant to obtain the value for this tag: ${sourceDir}.

Two other commands present in the above buildfile are:

<deltree dir=”${ outputDir }” />
<mkdir dir=”${ outputDir }” />

These commands are used to ensure that there are no extraneous files in the outputDir (or classes directory when dereferenced as mentioned above). The first command removes the entire tree contained under the outputDir. The second command creates the directory again.

The last line of major interest to the developer is the following compilation line:

<javac srcdir=”${sourceDir}” destdir=”${outputDir}” />

The javac command requires a source directory (the input location of the .java files) and a destination directory (the output location of the .classes file). It is important to note that all directories must either exist prior to the running of the ant command or be created using the mkdir command. Ant does not create directories based upon intuition, so you must create the outputDir, using the mkdir command prior to the compilation step above.

After the compile task has completed, the deploy task will perform the copy operation to move all JSP files from the source directory to a deployment directory. By using the copydir command, you copy the entire JSP directory from one location to another. I used the copyfile command to copy a single properties file as part of the build.

While it took several lines to explain the example, it should be evident that Ant is an easy-to-use tool. Using this build file as a starting point, you should be able to incorporate Ant into your development effort.

Extending Ant:

Two Ant extensions are interesting to discuss at this point. They are increased reporting and the ability to distribute code remotely using Ant.

If you wanted to extend Ant’s functionality to provide notification when certain steps in the build process are completed or are in progress, you can create a class to listen to the Ant process as shown in the following example.

You can create a class that implements the BuildListener interface. Using this class, you can catch each event that is part of the Listener:

public void buildStarted(BuildEvent event);
public void buildFinished(BuildEvent event);
public void targetStarted(BuildEvent event);
public void targetFinished(BuildEvent event);
public void taskStarted(BuildEvent event);
public void taskFinished(BuildEvent event);
public void messageLogged(BuildEvent event);
The BuildEvent event object contains the following methods by which you can obtain information about the current status of the build:

public Project getProject() ;
public Target getTarget() ;
public Task getTask();
public String getMessage();
public int getPriority();
public Throwable getException();

So if you wanted to write a reporting tool, you need only to create a class that implements the BuildListener interface and process the BuildEvents as needed by your design. Because Ant initiates the Java classloader, you must specify the listener as part of your command line arguments. For example:

ant -listener org.apache.tools.ant.XmlLogger

This listener is included with the Ant distribution and outputs an XML representation of the build process to a file called “log.xml”.

Conclusion:

The biggest takeaway from this article should be the importance of a build process to construct your environment in an effective and efficient manner. With that understanding, it is less important that you use Ant or some other homegrown scripting mechanism. However, I feel that Ant is an easy-to-learn platform-independent tool that provides expansion as needed. The XML involved in the buildfile is easy to read and understand, and a large number of already supported commands perform the vast majority of your build tasks without expansion. If you find a limitation, you can expand Ant to include your modifications.

Please Post Your Comments & Reviews

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.