Development and Build System with ANT - Properties
(Page 6 of 11 )
Ant provides the ability for a project to have a set of properties. Properties are simple strings that you can access using the ${propertyName} notation. Whether you need to specify the location of a needed library many times or the name of a CVS repository, properties give you the flexibility to defer until runtime a set of values to be used in the build.
There are several ways to set a property. You can set it individually to the Ant buildfile via the D command-line option (see Table 3-1), or in bulk, from standard Java properties files by using the propertyfile option.
There are also several tasks that deal with properties. The property task enables the setting of a property by name. All property tasks are idempotent, which means that once a property’s value has been set it will remain unchanged for the remainder of the build. The immutability of properties in Ant is often a source of confusion, because as developers you often tend to think of them as variables.
NOTE
The <ant> and <antcall> tasks both span a new build by starting another instance of an Ant project. The <ant> task calls an external buildfile, and the <antcall> task calls a target on the current buildfile. For both tasks, all of the properties of the calling project become available on the spawned projects, unless you set the inheritAll attribute to false, in which case only those properties passed on the command line become available to the spawned projects.
The simplest way to set a property’s value is to use the property task. For example. To set a property named src, which could be later accessed using ${src}, you would use the property task as follows:
<property name="src" location="src" />
The src property would be an absolute path that refers to the location of the src directory relative to the basedir directory.
BEST PRACTICE
Properties should be used with care. The two main uses of properties are, for items whose value might change from build to build or for items whose value is calculated and used more than once during the build.
Many Ant properties are also available implicitly and are composed from the system properties such as ${java.version}.
For any but the simplest project you can load a property file using the file attribute of the property task, thereby taking into account differences in user configurations, as follows:
<property file="build.properties"/>
Other tasks that deal directly with properties include the following:
- LoadProperties: Loads the contents of a file as properties (equivalent to using the file attribute for the property task.
- LoadFile: Loads a text file into a single property.
- XMLProperty: Loads properties from an XML file. See the Ant documentation for the specific format of the XML file.
- EchoProperties: Displays all available properties in the project.
Many other tasks use properties as a way to take parameters in or out. For example, a common practice is for a task to have an attribute that takes the name of an nonexistent property to be set in case of a specific event, such as the possibility of the task failing.
BEST PRACTICE
We recommend using a properties file named build.properties to store any overridden default values. This property file shouldn’t be kept in the source-code repository, but instead you should add a sample properties file named build.properties.sample along with instructions on how to configure the build.properties file.
Datatypes
Ant’s datatypes are primitive constructs that provide frequently required information in the processing of a buildfile. Their purpose is to simplify a task by encapsulating some information required and providing a simple way to manipulate it.
Several of Ant’s built-in datatypes provide a structure that encapsulates information about a set of related resources such as files, environment variables, or even complex mappings between input and output files. Knowing how to properly use the Ant’s datatypes will help you kept your buildfiles simple and efficient.
Datatypes and Properties in Action: A Simple ExampleMany of Ant’s tasks need to manipulate a file or groups of files. A typical need in a build is to specify a set of JAR files to be included in the classpath for certain tasks. Imagine that you’re building a simple application with a directory structure, as shown in Figure 3-4.

Figure 3-4. Sample directory structure for datatypes and properties
The following sample buildfile snippet shows a build for which two path structures (datatypes) are defined, one with an id of class.path and the other with an id of all.source.path. These two datatypes are then used in the target named compile, which uses the javac task to compile the classes referenced by the path reference by the id all.source.path.
<?xml version="1.0"?>
<project name="My Build" default="all" basedir=".">
...
<property name="lib" location="lib"/>
<property name="src" location="src"/>
<property name="classes" location="classes"/>
<property name="build" location="build"/>
<property name="src-java" location="${src}/java"/>
<property name="src-generated" location="${build}/generated-code/java"/>
<property name="struts-lib" location="${lib}/struts"/>
...
<path id="class.path">
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
<fileset dir="${struts-lib}">
<include name="*.jar"/>
</fileset>
</path>
<path id="all.source.path">
<pathelement path="${src-java}"/>
<pathelement path="${src-generated}"/>
</path>
...
<target name="compile" description="Compiles all sources.">
...
<javac
destdir="${classes}"
classpathref="class.path"
debug="on"
deprecation="on"
optimize="off">
<src>
<path refid="all.source.path"/>
</src>
</javac>
</target>
The class.path path structure uses two instances of the fileset datatype to group under a common classpath all the JAR files included in the directories referenced by the lib and struts-lib properties. The path element is an example of an indispensable datatype that enables you to reuse path information in your builds. The fileset datatype is a typical example of Ant’s pathlike structures. It encapsulates a group of files defined via nested patternset structures. For example, to create a fileset that includes all JAR files under the ${lib} directory, you can use the following fileset definition:
<fileset dir="${lib}">
<patternset>
<include name="*.jar"/>
</patternset>
</fileset>
The fileset datatype contains an implicit patternset structure, which means that you can use shorthand to rewrite the fileset definition as follows:
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
You can further compact the fileset definition by using the include in the property form, rather than as a nested element:
<fileset dir=”${lib} include=”*.jar” />
The path datatype can also make use of nested pathelements, as shown in the definition of the all.source.path path structure. It uses the pathelement datatype to reference the locations defined by src-java and src-generated properties.
Path is a typical Ant pathlike structure. When dealing with paths or classpaths, Ant provides pathlike structures that can be used as nested elements on most tasks. In the previous example, you can see that the two pathelements defined at the top of the buildfile are then used by reference in the context of the javac task. The class.path path is passed to the classpathref attribute of javac to determine the classpath for compilation and the all.source.path is used by creating a new pathelement, which is nested inside the src nested element of the javac task.
As a build’s complexity increases so do the patterns for selecting files. Pathlike structures enable the reuse of path information and help keep the growth of buildfiles under control.
NOTE
One of the criteria used in choosing many of the tools in this chapter was whether the tool provided an Ant task.
Next: Case Study: Building the Technology Conference Management System with Ant >>
More Java Articles
More By Apress Publishing
|
This article 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). Check it out at your favorite bookstore today. Buy this book now.
|
|