Ant Best Practices: Use properties for configurability

Ant Best Practices: Use properties for configurability(Photo taken from Catatronic's Photostream)

First time? Have a look here.

Okay. This time, it's about properties. A property represents some fact about your build system: where something is located, or the state of something.

A property can look like this:

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

or if you're dealing with a path, then it ought to look like this:

<property name="foo.dir" location="bar"/>

The point that Eric makes in today's practice is that once you represent everything that is liable to change with a property, you can pass in new values, and override them, or simply change them and enjoy the DRY-ness of it all.

There's a couple of things that I want to hammer home here:

  • Properties in Ant are immutable. This is a good thing.
  • You can use property files to declaratively load properties.

It takes some getting used to, the idea that you can never change a value of an Ant property. Why is this a good thing? Because you can use this to cascade down through default values. You can always declare the properties that you most want to use first, and then declare the default ones last. And you know that if you pass a property on the command line with a -D (taken straight from nant, that one), you'll know it's been set. Even Nant, which chose not to do consistently immutable properties and is in my opinion poorer for it, treats properties from the command line as immutable.

So repeat. Properties are immutable. And that's fine.

Now, onto the property files. There's always some variation in IT projects. That instance of your service needs to talk to a different database. That developer needs to build with a different path because he's got the worst computer in the room and they gave him an extra disk as a consolation prize.

(it's worth dropping that computer down a flight of stairs if it affords you more consistent developer builds - not that I'd ever advocate destruction of company property)

Property files allow you to address the chaos by overriding the defaults. No don't go and make the names of the property files too odd. Base them on a property that you can easily get, like the hostname of the machine or the name of the user. By using that as a key, you can load the property file for the correct user in one line of Ant file:

<!-- override the defaults -->
<property file="${user.name}.properties"/>

<

In the example above, user.name is a property given to you by the Java Runtime Environment, so you can guarantee that it's going to be there. You can place this code in the body of the Ant file so that it's available to any target. Wrapping this in a target is a recipe for disaster as that target becomes a dependency for ever other target in the build system. I had nightmares about a target called resolve.properties target at one project that I did. They also had the worst coffee in West London, if not the world.

DevOps New Zealand