-
22 January 2010, 17:08
Apache Ant - Properties
In my last post on Ant, "The Basics of Apache Ant", you learned what an external DSL is, and in the end you learned how to use this DSL to clean and compile. Now, I'd like to make you familiar with one more little feature that programmers will find very useful--Properties.
You may have noticed how often a few strings appeared in my last post, namely "bin" and "src". In that small example, it may not really matter to you, but in a larger build file, being able to change all references of "bin" to "target" by only making a change in one place will prove very valuable. The concept of "magic numbers", etc. should be familiar to all programmers out there.
The first thing to note is that Properties are immutable, meaning they cannot change once set. Whoever sets a property first, freezes it for the rest of the build. This should never be a problem; in fact, it can provide you with a little extra flexibility.
There are several different ways of setting Properties, and I'll only go over the ones that I have actually used in the past. I have written many build scripts using Ant, and never have I needed some of the options that are provided. For the full reference, see the manual page for the Property Task.
This is probably the most common use and most straight-forward use of the Property Task:
Here, we see that the Property<property name="dir.bin" value="bin"/>dir.binis being set tobin. Now, if we want to reference thebindirectory, we can simply reference it anywhere in the file by typing${dir.bin}in any attribute value. One "gotcha" that you may have realized is that you cannot reference a Property until it has been set. It will not blow up on you, but it will simply be the empty string. Like all my programs (in any language), I declare my constants at the beginning of the file, before any methods, or targets in the case of Ant.The other two techniques that I use for setting Properties are very similar, so I will mention them both at once.
and<property file="build.properties"/>
The former will load a standard Java Properties file from the local computer. You can specify either a relative or absolute path. The latter does the same, but from a URL.<property url="http://example.com/build.properties"/>The final way that I use the Property Task is to get at the system environment variables.
This will read in all the system environment variables and store them in properties, prefixed with "env". This could be useful if you want to get at the<property environment="env"/>ANT_HOMEorLD_LIBRARY_PATHvariables.I mentioned earlier that immutability can provide some added flexibility. How is this so? Well, often, I will have two targets for compiling&emdash;one for debug builds and one not. Here is a possible compile target:
That might look stupid to have the "DEBUG" property set immediately before using it, but that's part of the trick. Take a look at this alternative target for making a non-debug version:<target name="compile" depends="init"> <property name="DEBUG" value="true"/> <javac srcdir="src" destdir="bin" debug="${DEBUG}"/> </target>
The<target name="compile_non_debug" depends="init"> <property name="DEBUG" value="false"/> <antcall target="compile"/> </target>compile_non_debugsets theDEBUGproperty to "false" and then makes use of another taskantcallto execute thecompiletarget. SinceDEBUGhas been set to "false" incompile_non_debug, it cannot be set to "true" later. I have reused my other task, but in a different way, thanks to Properties.