This article will describe some of the development tools that are available from the Java Open Source community and explore how they can help you create high-quality software in a predictable and reproducible fashion, saving you precious time and money. It is taken from chapter three of the book Enterprise Java Development on a Budget, written by Brian Sam-Bodden and Christopher M. Judd (Apress, 2004; ISBN: 1590591259).
Development and Build System with ANT - Introduction to Ant (Page 4 of 11 )
Ant’s architecture is similar to the make utility in that it’s based on the concept of a target. In Ant a target is a modular unit of execution that uses tasks to accomplish its work. An Ant target has dependencies and can be conditionally executed. A build is usually composed of some main targets that will typically accomplish some coarse-grain process related to an application’s build, such as compiling the code or packaging a component. These main targets might make use of other subtargets (usually via dependencies) to accomplish their job.
Underneath the covers, tasks are plain Java classes that extend the org.apache.tools.ant.Task class although any class that exposes a method with the signature void execute() can become an Ant Task. One of Ant’s great advantages is its extensibility. Ant tasks are pluggable plain Java classes. To write a task all you need to do is extend the Task class and add some code to the execute method. Ant comes loaded with myriad tasks to accomplish many of the things needed during a typical build. These tasks are referred to as the “core tasks” and the “optional tasks.” There are also a countless number of third-party tasks, whether they’re commercial, freeware, or open-sourced.
The scope of Ant’s contribution to Java development isn’t obvious at first, especially on small projects. But once complexity begins to creep in and you have multiple developers, you’ll find that Ant becomes the glue that can help your team work in synchronization. It can basically remove the need for a full-time build “engineer.” This is largely the case with most Open Source Java projects and their success should be a testament to the effectiveness of continuous integration using Ant.
Ant isn’t without its critics, however. Many have failed to understand that Ant was never meant to be a full-fledged scripting language but a Java-friendly way to automate the build process in a simple declarative, goal-oriented fashion. Since its inception, many scripting-like features have been added to Ant in the form of custom tasks, and the arguments between camps that want a full-scripting language and ones that want a simple, dependency-driven build system continue to this day. In our opinion there is no right answer; scripting is programming and you know the issues that arise with that. On the other hand, Ant’s simple declarative ways make it hard to do write-once and reuse builds across different projects. Ant’s reusability is at the task level. In his essay, “Ant in Anger,” Steve Loughran recommends that to achieve the level of complexity that most developers turn to scripting to achieve, Ant builds can be dynamically generated on a per-project basis using something like eXtensible Stylesheet Language Transformations (XSLT).3For those looking for a full-fledged scripting engine based on XML, the Apache Jakarta Commons project provides Jelly.
Obtaining and Installing Ant
Ant can be obtained fromhttp://www.ant.apache.orgin binary and source distributions, or you can obtain the source code through CVS. Ant is a pure Java application, therefore the only requirement to run it is that you have a compliant JDK installed and a Java API for XML Processing (JAXP)–compliant parser (Ant ships with the latest Apache Xerces2 parser). Ant is distributed as a compressed archive (.zip, tar.gz, and tar.bz2). Once the archive has been uncompressed to a directory (this directory is referred to as ANT_HOME), it’s recommended that you add the environment variable ANT_HOME to your system and the bin directory under the ANT_HOME directory to your system’s executable path. The bin directory contains scripts in many different formats for the most popular platforms. These scripts facilitate the execution of Ant and include DOS batch, UNIX shell, and Perl, and Python scripts. Ant also relies on the JAVA_HOME environment variable to determine the JDK to be used.
CAUTION If you only have the JRE installed (a rare case for most Java developers) many of Ant’s tasks will not work properly.
To verify that Ant is installed correctly, at the command prompt type:
If the installation was successful you should see a message showing the version of Ant and the compilation date:
Apache Ant version 1.6.0 compiled on December 18 2003
Ant’s Command-Line Options
Ant is typically used from the command line by running one of the scripts in the bin directory. Ant’s command line can take a set of options (prefixed with a dash) and any number of targets to be executed, as follows:
ant [options] [target target2 ... targetN]
Table 3-1 shows the options available from the command line. You can access them by typing ant -help. By default Ant will search for a file named build.xml unless a different file is specified via the Buildfile option.
Table 3-1. Ant Command-Line Options
Prints the help message showing all available options.
Displays all targets for which the description attribute
has been set.
Prints the version of Ant.
Prints a diagnostics report that shows information like
file sizes and compilation dates; useful for reporting
Minimizes the amount of console output produced
Table 3-1. Ant Command-Line Options (Continued)
Ant will use this class to handle input request. By default input requests are handled via the standard in (stdin).
Ant will search for the given filename by traversing
upwards from the current directory until it finds the file.
The file system to use.
(mospagebreak title=A Simple Ant Example}
Figure 3-1 shows a simplified view of what a simple Ant build entails. The root of an Ant build is the project element, which contains one or more targets and at least one default target. In this case the simple build contains three targets named Target A, Target B, and Target C, with Target C being the default target. As shown in the zoomed view of Target B, a target can contain zero or more tasks.
Figure 3-1. A simplified view of an Ant build
Ant controls the build process with a description file. In Ant the description file is typically referred to as a “buildfile” or “build script.” The Ant buildfile is an XML file whose root is the project element that contains child nodes that represent the targets. An Ant buildfile representing a build similar to the one depicted in Figure 3-1 would look like this:
As you can see, for a simple buildfile the XML format makes it easier to discern targets from one another.
The project element can have three attributes: name, default, and basedir. Only the default attribute is required, but we recommend that you use the name attribute especially because many IDE Ant editors use this attribute for display purposes. The name attribute comes in handy when dealing with more than one buildfile.
For a project with a single buildfile (build.xml) we recommend that you use the name of the project for the name attribute of the project element. For projects with multiple buildfiles we recommend that you name each one according to its intended functionality and that the name attribute should be the same as the filename without the .xml extension.
The default attribute determines the default target to be executed for the buildfile. Finally the basedir attribute determines the base directory for all file-related operations during the course of a build. In the previous example it’s simply the current directory where the buildfile resides, and because this is the default value the attribute could have been omitted. This setting is important especially if you’re using multiple buildfiles in different subdirectories of an application directory structure and you want a uniform way to refer to paths across all buildfiles.
The Build Stages
An Ant build has two stages: the parsing stage and the running stage. During the parsing stage the XML buildfile is parsed and an object model is constructed. This object model reflects the structure of the XML file in that it contains one project object at the root with several target objects, which themselves contain other objects representing the contents of a target such as tasks, datatypes, and properties.
Ant scripts can contain top-level items other than targets. These can include certain tasks and datatypes. These elements are grouped in order of appearance into an implicit target that gets executed right after the parsing process ends and before any other targets are executed.
During the runtime phase Ant determines the build sequence of targets to be executed. This sequence is determined by resolving the target’s dependencies. By default, unless a different target is specified, Ant will use the default target attribute as the entry point so it can determine the build sequence.
Let’s execute the sample buildfile for the sample build shown in Figure 3-1 in order to get acquainted with Ant and some of the command-line options shown in Table 3-1. First type the contents shown in the listing to a text file and save it as build.xml. To run it, simply change to the directory where the buildfile is located and type the following:
The output should look like this:
Buildfile: build.xml Target A: [echo] Performing Step A Target B: [echo] Performing Step B [echo] Echo is one of many Core Tasks Target C: [echo] Performing Step C BUILD SUCCESSFUL Total time: 1 second
The output shows that Ant executed the build file successfully and that it took 1 sec to execute (execution times will vary from system to system.) From the output, you can see that the targets were executed in the following sequence: Target A, Target B, and Target C. To see a bit more detail you can run Ant again using the -v command-line option, which will show you some extra information as shown:
Apache Ant version 1.5.3 compiled on April 16 2003 Buildfile: build.xml ... Build sequence for target `Target C' is [Target A, Target B, Target C] Complete build sequence is [Target A, Target B, Target C] ... BUILD SUCCESSFUL Total time: 1 second
First, notice that the output shows that the intended target is Target C, which was defined as the build’s default target. Ant resolved the default target dependencies to arrive at the build sequence [Target A, Target B, Target C] as shown at the top of the console output.
The text enclosed in the <echo> elements in each of the targets is shown on the console as each target is executed. The <echo> task is one of many built-in tasks provided by Ant. For example, a quick browse of the online documentation shows that the Echo task sends the text enclosed to an Ant logger. By default Ant uses the DefaultLogger, which is a class that “listens” to the build and outputs to the standard out. Specific loggers can be selected on the command line by using the –logger option. Further examination shows that the Echo task is well integrated with the logging system and that it can be provided with a level attribute to control the level at which the message is reported.
We decided against regurgitating the contents of the online documentation, therefore we’ll explain some of Ant’s tasks in context as you set out to build the tiers of the TCMS system. The best place to learn about all the available Ant tasks is from the online manual located athttp://ant.apache.org/manual/index.html.
The previous run of the sample script assumed that you wanted to run the default target. To run a specific target you can indicate the target in the command line as follows:
ant "Target A"
Notice that target names are case sensitive and that double quotes are required for any target names that contain spaces. The resulting output should look like this:
Buildfile: build.xml Target A: [echo] Performing Step A BUILD SUCCESSFUL Total time: 1 second