ANT script good practices – few thoughts
Posted by Piotr Gabryanczyk on September 15, 2008
Here are some techniques which should help with it:
All the OO principles apply!
When you need custom functionality for your project i.e. custom make step – do not bloat the common files with conditional logic. Extract common stuff to macrodefs and create separate files and/or targets for custom functionality in local project directory. Basically all the OO principles apply!
Break it down and modularize
You wouldn’t like to have just one big class in your project – do the same with ant script, break it down and modularize
Stop writing generic ant targets parametrized by global properties
Replace them with macrodefs. See:
http://ant.apache.org/manual/CoreTasks/macrodef.html
Stop using global properties
Don’t use them, unless they are really global i.e. project.name, project.version. In general they are evil as global variables and singletons are. See:
http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx
http://www.cs.usfca.edu/~wolber/courses/110/lectures/globals.htm
Use convention over configuration design paradigm.
What does it mean? Basically this:
Instead of writing (unneccessary abstraction and complexity):
<property name="project.dir" value="${basedir}"/>
<property name="test.result.dir" value="${project.dir}/build/testresult"/>
<javadoc dest="${test.result.dir}>
...
We would write:
<javadoc dest="build/testresult">
...
Simpler and more readable!
See more here:
http://en.wikipedia.org/wiki/Convention_over_Configuration
Use maven-like project directory structure
This supports convention over configuration approach and simplifies your build scripts.
project
- src
+- main
+- java
+- config
+- scripts
+- ...
+- test
+- java
+- config
+- ...
- lib
+- compile
+- runtime
+- spring-2.0.jar
+- jakarta-commons
+- commons-io.jar
+- commons-???.jar
+- ...
+- test
- ant (contains common ant tasks - it should be symbolic link as this scripts should be shared)
+- ant-common.xml
+- ant-test.xml
+- ...
- target ( temporary directory, only RW area of the project, equivalent to build)
- modules (if the code contains modules build separately like c++)
+- SomeNativeLib
+- src
+- lib
+- ...
+- OtherJavaModule
+- src
+- lib
+- ...
- build.xml
Enjoy!

ittay said
just use buildr (http://incubator.apache.org/buildr/):
break functionality into files, classes
write regular functions instead of macrodefs
don’t need to rely on an implementation of functionality in Java as ant relies on tasks (but you can call any ant task)
user normal variables, arrays and hashes. no more property hacking!
use layouts
use extensions
Piotr Gabryanczyk said
Nice one, I will investigate it.
tommile said
Well, nothing much here. Just trying to be of help