Ant Properties, Datatypes & References
Datatypes
The following datatypes are available in Ant:
- Paths - An ordered list of files and directories.
- Classpath is a variant of this.
- Filesets - A collection of files rooted from a specified directory.
- Patternsets - A collection of file matching patterns.
- Filtersets
Properties
This is a way of defining variables that you can use in your build:
- They are defined as key-value pairs.
- They are immutable.
Built-in Properties
You can see a list of system properties such as:
%{os.name}
at the following link: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ System.html#getProperties().
Storing Locations in Properties
To allow for processing of file-paths you should use the location
attribute instead of value
:
<property name="dir" location="somedir"/>
This will allow prepending of the basedir
and formatting the path for the OS.
Setting Properties
Setting Properties via Task
You can set, and use, properties by using the <property>
task like so:
<property name="build.debug" value="on"/>
<javac srcdir="src" debug="${build.debug}"/>
Setting Properties via Command-Line
You can set properties on the command line using the -D<property>=<value>
syntax:
$ ant -Dbuild.debug=off -f build.xml
You can also include a property file:
$ ant -propertyfile build.properties
-D
flags take precedence over the property file.
Setting Properties from File
You can create a file, such as build.properties
to hold your values in an ini
style:
build.debug=off
build.dir=build
output.dir=${build.dir}/output
This properties file can then be loaded using the following task:
<property file="build.properties"/>
Setting Properties from Environment Variables
We can store all the environment variables in a property called env
like so:
<property environment="env"/>
We can then access them using their name:
<echo message="The PATH is: ${env.PATH}">
Global Properties
There is no concept of scope for properties but if you want them to be available for multiple targets, you should assign them under <project>
:
<project name="test">
<property name="..." value="..."/>
<target>
...
</target>
</project>
This ensures they are executed before the target.
<available>
We can set a property when a resource is available by using this task:
<property name="project.jar" value="./dist/project.jar"/>
<available file="${project.jar}"
type="file"
property="project.jar.present"
/>
<echo message="file ${project.jar} is present=${project.jar.present}"/>
This method can work on:
- Classes in a Classpath
- Files & Directories
- Resource Files (
.jar
files)
The man page is here: https://ant.apache.org/manual/Tasks/available.html.
Conditional Execution
We can use if
and unless
to execute tasks depending on a property:
<target name="build-module-A" if="module-A-present"/>
<target name="build-module-B" unless="module-A-present"/>
- Unset properties are falsy.
- Everything else is truthy.
References
We can save several attribute definitions using a reference:
<path id="compile.classpath">
<pathelement location="${lucene.jar}"/>
<pathelement location="${tidy.jar}"/>
</path>
We can then use these pathelements
else where by using refid
:
<path id="test.classpath">
<path refid="compile.classpath"/>
<pathelement location="${junit.jar}"/>
<pathelement location="${build.dir}/classes"/>
<pathelement location="${build.dir}/test"/>
</path>
We can also use datatypes other than path
.
If you are going to reuse this datatype then you can name it using a property:
<project name="ref-classpath" basedir="dist">
<path id="test.classpath">
<pathelement location="build/classes"/>
<pathelement location="src"/>
</path>
<property name="path" refid="test.classpath"/>
<echo>path is ${path}</echo>
</project>
This makes a standalone datatype.
This will produce an output like so:
$ ant
Buildfile: /home/ben/ref-classpath/build.xml
[echo] path is /home/ben/ref-classpath/dist/build/classes:/home/ben/ref-classpath/dist/src
BUILD SUCCESSFUL
Total time: 0 seconds
Notice how this takes into account the basedir
.