Dashboard > JJGuidelines > Home > Appendix B - Guidelines Rules > B.1. Ant rules
JJGuidelines Log In | Sign Up   View a printable version of the current page.
B.1. Ant rules
Added by Alexander Bollaert, last edited by Alexander Bollaert on Jan 10, 2007  (view change)

Ant rules

Overview

Table B.1. Ant rules

Rules
ANT_001: Use the default build.xml build filename
ANT_002: Do Not Hard Code An Absolute Directory Or File Path
ANT_003: Suffix The Name Of A Property That Represents A Directory With .dir
ANT_004: Use Package Like Names To Namespace A Property Or Target
ANT_005: Depend Only On Direct Dependencies
ANT_006: Make Each Target Directly Runnable
ANT_007: Use The location Attribute For A File Or Directory Based Property
ANT_008: Use The zipfileset Task To Create Archives
ANT_009: Keep Your Build File Platform Independent When Possible
ANT_010: Set A Needed Environment Variable In The Build Script

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"/> 
<!-- if tomcat.home is defined in localProject.properties, --> 
<!-- it is ignored in 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"/> 
<!-- Environment properties will be env.path, etc--> 
<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"> 
<!-- Can now be run --> 
<!-- ... --> 
</target> 
<target name="ear" depends="war" description="Makes a ear file with the war file"> 
<!-- Does not directly depends on the compile target --> 
<!-- ... --> 
</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"> 
<!-- Depends on compile. --> 
<!-- Can only be run as part of the ear target --> 
<!-- ... --> 
</target> 
<target name="ejb"> 
<!-- Depends on compile. --> 
<!-- Can only be run as part of the ear target --> 
<!-- ... --> 
</target> 
<target name="ear" depends="compile, war, ejb"> 
<!-- Does not directly depend on buildClasses. --> 
<!-- ... --> 
</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>

Site powered by a free Open Source Project / Non-profit License (more) of Confluence - the Enterprise wiki.
Learn more or evaluate Confluence for your organisation.
Hosted by JavaLobby
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.5 Build:#520 Jun 27, 2006) - Bug/feature request - Contact Administrators