Ant: Properties

The variable like things in Ant files (but they aren't really variables)

In an Ant build.xml file, you’ll often see lines such as these:

   <property name="jar.file" value="build/jar/CS56Parser.jar"/>

The idea here is that jar.file becomes the name of a property that stands for the filename build/jar/CS56Parser.jar

The general idea is that if you later want to change the name of jar file created by this build.xml file, you only have to change it in one place. You can then write code such as this in your jar task (the one that creates the jar file)

  <jar destfile="${jar.file}" basedir="build/classes">
  ...

and this when you want to use the java task to run the jar file:

 <java jar="${jar.file}" fork="true"/>

These bits of your code never have to change from one build.xml file to another, and if/when you change the name of your jar file, you only have to change it in once place.

You can think of the ${} syntax as a dereference operation.

A common idiom: <property name="src" location="src"/>, etc.

A common idiom, which looks a bit odd at first, is this one:

  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist" location="dist"/>

This may seem redundant. In fact, if you are strongly committed to the convention that the source directory is caled src, the build directory is called build and the distribution directory is called dist, then this these property settings are unnecessary.

Their purpose is to decouple the roles of source, build, and distribution from these specific names, so that if you later, you decide to change those names in practice, you only have to change them in one place in your code.

That is, later in your code, instead of putting:

<target name="compile" description="compile the source">
    <javac srcdir="src" destdir="build"/>
</target>

Instead, you write:

<target name="compile" description="compile the source">
    <javac srcdir="${src}" destdir="${build}"/>
</target>

The ${src} syntax means to substitute the value of the property src in place of the ${src} expression.

If you decide to go with the name source instead of src, or you have a nested directory structure such as src/main/java, you can define the property accordingly:

Note that in this case, the second attribute of the XML element is location rather than value. This indicates that the property refers to a file or directory.

Properties are immutable

Something that can be confusing is that if you set a property in a build.xml file, and than later set it to something else, the second property setting is simply ignored.

Consider this example:

<project>

 <property name="foo" value="fiddle" />
 <property name="foo" value="bar" />

 <target name="baz">
  <echo> foo has the value ${foo}</echo>
 </target>

</project>

We run this, and get the following output. Note that the first value of foo is the one that gets printed, and there is no error messages indicating that the second property setting was ignored.

Phills-MacBook-Pro:~ pconrad$ ant baz
Buildfile: /Users/pconrad/build.xml

baz:
     [echo]  foo has the value fiddle

BUILD SUCCESSFUL
Total time: 0 seconds
Phills-MacBook-Pro:~ pconrad$ 

If we reverse the order of the property assignments, we see again that the first property value set is the one that sticks:

<project>

 <property name="foo" value="bar" />
 <property name="foo" value="fiddle" />

 <target name="baz">
   <echo> foo has the value ${foo}</echo>
 </target>

</project>

Result:

Phills-MacBook-Pro:~ pconrad$ ant baz
Buildfile: /Users/pconrad/build.xml

baz:
     [echo]  foo has the value bar

BUILD SUCCESSFUL
Total time: 0 seconds
Phills-MacBook-Pro:~ pconrad$