Ant rules
Overview
Table B.1. Ant rules
ANT_001: Use the default build.xml build filename
Use the default build.xml filename for your Ant build files. See it as a Ant build file naming convention.
ANT_002: Do Not Hard Code An Absolute Directory Or File Path
Do not hard code a directory or file path which starts from the root of the filesystem. This includes c:, d:, etc on windows and / on unix. There are 2 well know techniques to comply to this rule:
- Code relative to the base directory by using Ants build-in variable $basedir or a property task's location attribute. This is almost always appropriate for files or directories directly or indirectly under the base directory.
- Place the absolute paths in a separate global properties file which can be overwritten by a local properties file. See the section called "Reusing The Build File Across Environments". This is almost always appropriate for files or directories not under the base directory.
WRONG
<property name="tomcat.home" value="c:\tomcat"/>
<property name="build.dir" location="c:\MyProjects\MyProject\build"/>
<fileset dir="c:\MyProjects\MyProject\docs">
</fileset>
RIGHT
<property file="${basedir}/localProject.properties"/>
<property file="${basedir}/project.properties"/>
<property name="build.dir" location="build"/>
<fileset dir="${basedir}/docs">
</fileset>
ANT_003: Suffix The Name Of A Property That Represents A Directory With .dir
End the name of a property that points to a directory with .dir.
WRONG
<property name="dist" location="dist"/>
<property name="dist.ear" location="${dist}/ear"/>
<target name="dist" description="Builds distribution">
</target>
RIGHT
<property name="dist.dir" location="dist"/>
<property name="dist.ear.dir" location="${dist.dir}/ear"/>
<target name="dist" description="Builds distribution">
</target>
ANT_004: Use Package Like Names To Namespace A Property Or Target
Use the dots/lowercase notation to namespace properties and targets. Environment properties can only be named spaced with dots.
WRONG
<property environment="env"/>
<property name="distDir" location="dist"/>
<property name="distJarDir" location="${dist.dir}/jar"/>
<property name="distSrcDir" location="${dist.dir}/src"/>
<property name="version" value="1_0_0"/>
<target name="distJar" description="Builds the binary distribution jar">
</target>
<target name="distSrc" description="Builds the source distribution zip">
</target>
RIGHT
<property environment="env"/>
<property name="dist.dir" location="dist"/>
<property name="dist.jar.dir" location="${dist.dir}/jar"/>
<property name="dist.src.dir" location="${dist.dir}/src"/>
<property name="project.version" value="1_0_0"/>
<target name="dist.jar" description="Builds the binary distribution jar">
</target>
<target name="dist.src" description="Builds the source distribution zip">
</target>
ANT_005: Depend Only On Direct Dependencies
Do not make a target depend on targets which it does not depend directly on, even if one or several targets it depends on directly do depend on it directly. Instead make those targets depend on it.
 | If several targets which will be run depend on the same target, it will only be run once: before the first target that depends on it is run. |
WRONG
<target name="compile" description="Compiles the source files into class files">
</target>
<target name="war" depends="compile" description="Makes a war file with the class files">
</target>
<target name="ear" depends="compile, war" description="Makes a ear file with the war file">
</target>
RIGHT
<target name="compile" description="Compiles the source files into class files">
</target>
<target name="war" depends="compile" description="Makes a war file with the class files">
</target>
<target name="ear" depends="war" description="Makes a ear file with the war file">
</target>
 | However if the buildEar target directly uses one of the classes build with the buildClasses target, then it must depend on it. |
ANT_006: Make Each Target Directly Runnable
Do not create a target that does not depend on another target but does need the others target's build output in order to work. Instead make it depend on the target which creates build output which it needs.
WRONG
<target name="compile">
</target>
<target name="war">
</target>
<target name="ejb">
</target>
<target name="ear" depends="compile, war, ejb">
</target>
RIGHT
<target name="compile">
</target>
<target name="war" depends="compile">
</target>
<target name="ejb" depends="compile">
</target>
<target name="ear" depends="war, ejb">
</target>
 | If a project build becomes to long, one might be inclined to provide expert targets: targets that only rebuild part of the project and rely on parts still being available without depending on the targets that generate those other parts.
Instead of using expert targets, it is a better practice to divide your project in modules (with their own build.xml files) and build short term releases of modules to be used by other modules. |
ANT_007: Use The location Attribute For A File Or Directory Based Property
A property representing a single file or directory should be referenced through the location attribute instead of the commonly used value attribute.
WRONG
<property name="src.java.dir" value="${basedir}/src/java"/>
RIGHT
<property name="src.java.dir" location="src/java"/>
 | If the location attribute is a non absolute path it is taken relative to the project's basedir. |
ANT_008: Use The zipfileset Task To Create Archives
An archive file such as a WAR or EAR file needs to follow a certain directory structure. Do not create a temporary build directory to order all files according to the required directory structure, prior to archiving. Instead use the zipfileset task to copy the files directly into the correct path in the archive. This will avoid any copy overhead and make the build script gain noticable performance.
WRONG
<mkdir dir="${build.dir}/ear"/>
<mkdir dir="${build.dir}/ear/lib"/>
<copy todir="${build.dir}/ear/lib">
<fileset dir="${basedir}/lib/log"/>
<fileset dir="${basedir}/lib/xml"/>
</copy>
<mkdir dir="${build.dir}/ear/META-INF"/>
<copy todir="${build.dir}/ear/META-INF>
<fileset dir="${conf.dir}/ear">
<include name="weblogic-application.xml"/>
</fileset>
</copy>
<ear earfile="${dist.dir}/ear/${ant.project.name}.ear" appxml="${conf.dir}/ear/application.xml">
<fileset dir="${build.dir}/ear"/>
</ear>
RIGHT
<ear earfile="${dist.dir}/ear/${ant.project.name}.ear" appxml="${conf.dir}/ear/application.xml">
<zipfileset dir="${basedir}/lib/log" prefix="lib"/>
<zipfileset dir="${basedir}/lib/xml" prefix="lib"/>
<zipfileset dir="${conf.dir}/ear" prefix="META-INF">
<include name="weblogic-application.xml"/>
</zipfileset>
</ear>
ANT_009: Keep Your Build File Platform Independent When Possible
Avoid using platform dependent tasks such as:
- exec (executes a system command)
- chmod (works only on unix)
 | Check the Ant documentation for a task to verify that its platform independent. Very few Ant tasks are platform dependent. |
 | The exec target can specify the operation system(s) on which it should be run with the os attribute. This allows the build script to be run on multiple platforms, but doesn't make it platform independent. |
WRONG
<exec executable="copy">
<arg line="fileSrc.txt fileDest.txt"/>
</exec>
RIGHT
<copy file="fileSrc.txt" tofile="fileDest.txt"/>
ANT_010: Set A Needed Environment Variable In The Build Script
If a build script uses a platform depend program, an environment variable might need to be set. Do not depend on the local OS to be configured to contain it, instead define it in the build script, possibly based on a property fetched from the local properties file.
WRONG
<echo message="The environment variable SGML_CATALOG_FILES must be set" level="info"/>
<exec dir="${src.dir}/xml" executable="xmllint.exe">
<arg value="--catalogs"/>
</exec>
RIGHT
<exec dir="${src.dir}/xml" executable="xmllint.exe">
<env key="SGML_CATALOG_FILES" path="${basedir}/conf/dtd/catalog.xml"/>
<arg value="--catalogs"/>
</exec>