Ant

Apache Ant is a Java-based build tool.

Define a variable

<!-- Declare the variable(e.g Assign a number to PI variable). -->
<property name="PI" value="3.1415"/>
 
<!-- Using the variable(e.g echo the value of pi). -->
<echo message="${PI}"/>

Build in properties: http://ant.apache.org/manual/using.html#built-in-props

Core tasks: http://ant.apache.org/manual/coretasklist.html

Ant Installation

JDK is the software development kit for creating Java programs. Instructions below show you step-by-step how to install and set it up.

  1. Download Java Development Kit(JDK). Install it and follow the instructions shown on the screen.
  2. Create an environment variable JAVA_HOME and set its value to the folder path of you JDK installation(e.g. C:\Program Files\Java\jdk1.6.0_06).
    1. Depending on the version of your MS Windows, the steps below may be different but similar.
      • If you are using MS Windows XP, then open [Classic View]Control Panel->System->Advanced->Environment Variables.
      • If you are using MS Windows Vista, then open [Classic View] Control Panel->System->Advanced system settings->Advanced->Environment Variables.
    2. Under the User variables for XYZ(e.g. Administrator) section, click on the New... button.
    3. Enter the variable name as JAVA_HOME.
    4. Enter the variable value as the installation path for the Java Development Kit.
    5. Click on the OK button.
  3. Now, add the BIN folder of your JDK to the PATH environment variable.
    1. Under the User variables for XYZ(e.g. Administrator) section, search for the PATH variable. If the PATH variable is not listed, then create it. Otherwise, edit it.
    2. If you have to edit the PATH, then select it. Click on the Edit button and append the following line to the Variable value input field:
      ;%JAVA_HOME%\bin
       
    3. If you have to create the PATH, then click on the New button. Set the Variable name to PATH and then set the Variable value to
      %JAVA_HOME%\bin
       
    4. Click on the OK button.
    5. Open a new Command Prompt for the change to take effect and then execute the following command:
      javac -version
       
      It should show the version number of your Java Compiler(javac).

Built-in Properties

Property Description
basedirthe absolute path of the project's basedir (as set with the basedir attribute of ).
ant.filethe absolute path of the buildfile.
ant.versionthe version of Ant
ant.project.namethe name of the project that is currently executing; it is set in the name attribute of .
ant.java.versionthe JVM version Ant detected; currently it can hold the values "1.2", "1.3", "1.4" and "1.5".
ant.homehome directory of Ant
java.versionJRE version
java.vendorJRE vendor
java.vendor.urlJava vendor URL
java.homeJava installation directory
java.vm.specification.versionJVM specification version
java.vm.specification.vendor JVM specification vendor
java.vm.specification.name JVM specification name
java.vm.versionJVM implementation version
java.vm.vendorJVM implementation vendor
java.vm.nameJVM implementation name
java.specification.versionJRE specification version
java.specification.vendorJRE specification vendor
java.specification.nameJRE specification name
java.class.versionJava class format version number
java.class.pathJava class path
java.ext.dirsPath of extension directory or directories
os.nameOperating system name
os.archOperating system architecture
os.versionOperating system version
file.separatorFile separator ("/" on UNIX)
path.separatorPath separator (":" on UNIX)
line.separatorLine separator ("\n" on UNIX)
user.nameUser's account name
user.homeUser's home directory
user.dirUser's current working directory

Using timestamp

Example of using timestamp

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="create_directory_with_timestamp" name="Show how to use tstamp.">
 
  <target name="create_directory_with_timestamp">
 
    <!-- Declare the timestamp format of DAY_TIME_NOW -->
    <tstamp><format property="DAY_TIME_NOW" pattern="yyyy-MM-dd_HH.mm.ss" /></tstamp>
 
    <!-- Using DAY_TIME_NOW to create a directory called DAY_TIME_NOW -->
    <mkdir dir="${DAY_TIME_NOW}"/>
 
  </target>
 
</project>

Access environment variables

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- 
  Here is how you can access your environment variables.
  Note: Environment variables are specific to your system.
  More details can be found at http://ant.apache.org/manual/Tasks/property.html
 -->
<project basedir="." default="EnvironmentVariables" name="EnvironmentVariables">
 
  <target name="EnvironmentVariables">
    <property environment="my_env" />
    <echo>
      Here are sample environment variables in my operating system:
      ${my_env.PATH}
      ${my_env.COMPUTERNAME}
      ${my_env.ANT_HOME}
      ${my_env.JAVA_HOME}
    </echo>
  </target>
 
</project>

Ant build file for Docbook using Saxon

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="docbook_html" name="Docbook">
 
  <!--
    Change the followings according to your settings:
      -Path of saxon.jar
      -Path of docbook.xsl
      -Your xml docbook file(your_docbook.xml).
  -->
  <target name="docbook_html">
 
    <java jar="lib/saxon/saxon.jar"
      output="your_docbook_output.html"
      fork="true">
 
      <arg value="your_docbook.xml"/>
      <arg value="lib/docbook-xsl/html/docbook.xsl"/>
    </java>
 
  </target>
 
</project>

Ant build file to install xsltproc

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
Description: Install xsltproc:
              -Decompress all zip files from zip directory to the defined destination directory.
              -Generate paths to add in the PATH environment variable(environment.path.txt).
Author: Xuan Ngo
-->
<project basedir="." default="nothing" name="xsltproc_install">
 
  <property name="dir.separator" value="\"/>
 
  <property name="iconv" value="iconv-1.9.2.win32"/>
  <property name="zlib" value="zlib-1.2.3.win32"/>
  <property name="libxml2" value="libxml2-2.7.6.win32"/>
  <property name="libxslt" value="libxslt-1.1.26.win32"/>
 
  <!--=======================
  DEFAULT TARGET
  =======================-->
  <target name="nothing" description="By default, it does nothing.">
    <echo>By default, it does nothing.</echo>
    <echo>${os.name}</echo>
  </target>
 
  <!--=======================
  INSTALL TARGET
  =======================-->
  <target name="install" description="Install xsltproc.">
    <antcall target="errors_checking"/>
    <mkdir dir="${To.Dir}"/>
    <unzip src="zip/${iconv}.zip" dest="${To.Dir}"/>
    <unzip src="zip/${zlib}.zip" dest="${To.Dir}"/>
    <unzip src="zip/${libxml2}.zip" dest="${To.Dir}"/>
    <unzip src="zip/${libxslt}.zip" dest="${To.Dir}"/>
 
    <echo file="environment.path.txt">;${To.Dir}${dir.separator}${iconv}${dir.separator}bin;${To.Dir}${dir.separator}${zlib}${dir.separator}bin;${To.Dir}${dir.separator}${libxml2}${dir.separator}bin;${To.Dir}${dir.separator}${libxslt}${dir.separator}bin;</echo>
  </target>
 
  <!--=======================
  ERROR CHECKING TARGET
  =======================-->  
  <target name="errors_checking" description="Do GENERIC errors checking before installing xsltproc.">
 
    <fail message="&#xa;To.Dir parameter is required.&#xa;Example: ant -f xsltproc_install.xml -DTo.Dir=&quot;c:\xsltproc&quot;">
      <!-- Stop running if To.Dir is not set or it is empty. -->
      <condition>
        <or>
          <not>
            <isset property="To.Dir"/>
          </not>
          <length string="${To.Dir}" length="0" />
        </or>
      </condition>
    </fail>
 
    <fail message="zip/${iconv}.zip is missing.">
      <condition><not><available file="zip/${iconv}.zip"/></not></condition>
    </fail>
 
    <fail message="zip/${zlib}.zip is missing.">
      <condition><not><available file="zip/${iconv}.zip"/></not></condition>
    </fail>
 
    <fail message="zip/${libxml2}.zip is missing.">
      <condition><not><available file="zip/${iconv}.zip"/></not></condition>
    </fail>
 
    <fail message="zip/${libxslt}.zip is missing.">
      <condition><not><available file="zip/${iconv}.zip"/></not></condition>
    </fail>
 
    <echo>Errors checking: Passed!</echo>
  </target>
 
</project>

Ant with JUnit4

Sample Ant build file to run JUnit

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Filename: build.xml
  Note: You have to change the followings according to your environment:
          -<pathelement location="bin"/>
          -<pathelement location="lib/junit/junit-4.8.2.jar"/>
          -<test name="x.x.x.x.x.x" todir="${junit.output.dir}"/>
-->
<project basedir="." default="junit" name="Sample of Ant file for JUnit">
  <property name="junit.output.dir" value="junit"/>
 
  <path id="junit.classpath">
    <pathelement location="bin"/><!-- All compiled class should be under this folder -->
    <pathelement location="lib/junit/junit-4.8.2.jar"/>
  </path>
 
  <!-- Target: Run JUnit test classes. -->
  <target name="junit">
    <mkdir dir="${junit.output.dir}"/>
    <junit fork="yes" printsummary="withOutAndErr">
      <formatter type="xml"/>
      <!-- Add all your test class names here. --> 
      <test name="com.packageName.MyTestClassName.AddTest" todir="${junit.output.dir}"/>
      <test name="com.packageName.MyTestClassName.AddTest2" todir="${junit.output.dir}"/>
      <classpath refid="junit.classpath"/>
    </junit>
  </target>
 
  <!-- Target: Generate JUnit report. -->
  <target name="report">
    <junitreport todir="${junit.output.dir}">
      <fileset dir="${junit.output.dir}">
        <include name="TEST-*.xml"/>
      </fileset>
      <report format="frames" todir="${junit.output.dir}"/>
    </junitreport>    
  </target>
 
</project>



Sample Structure of my files and directories created by Eclipse

C:.
¦   .classpath
¦   .project
¦   build.xml
¦
+---bin
¦   +---com
¦       +---packageName
¦           +---MyClasses
¦           ¦       Add.class
¦           ¦
¦           +---MyTestClassName
¦                   AddTest.class
¦                   AddTest2.class
¦
+---junit
¦   ¦   all-tests.html
¦   ¦   allclasses-frame.html
¦   ¦   alltests-errors.html
¦   ¦   alltests-fails.html
¦   ¦   index.html
¦   ¦   overview-frame.html
¦   ¦   overview-summary.html
¦   ¦   stylesheet.css
¦   ¦   TEST-com.packageName.MyTestClassName.AddTest.xml
¦   ¦   TEST-com.packageName.MyTestClassName.AddTest2.xml
¦   ¦   TESTS-TestSuites.xml
¦   ¦
¦   +---com
¦       +---packageName
¦           +---MyTestClassName
¦                   0_AddTest.html
¦                   1_AddTest2.html
¦                   package-frame.html
¦                   package-summary.html
¦
+---lib
¦   +---junit
¦           junit-4.8.2.jar
¦
+---src
    +---com
        +---packageName
            +---MyClasses
            ¦       Add.java
            ¦
            +---MyTestClassName
                    AddTest.java
                    AddTest2.java

Compress everything

<project basedir="." default="build" name="myProjectName">
 
  <tstamp><format property="DAY_TIME_NOW" pattern="yyyy-MM-dd_HH.mm.ss" /></tstamp>
  <!-- 
    Will compress everything into myProjectName_YYYY-MM-DD_HH.MM.SS.tar.gz,
      except files with the format myProjectName_*.tar.gz and db directory.
  -->
  <target name="pack_code" description="Packing everything.">
    <tar compression="gzip" destfile="${ant.project.name}_${DAY_TIME_NOW}.tar.gz" 
      basedir="." 
      excludes="db/**, **/${ant.project.name}_*.tar.gz"  
    />
  </target>
 
  <!-- Or compress multiple specific files. -->
  <target name="compress_multiple_files">
    <tar compression="gzip" destfile="/path/to/my_archive.tar.gz">
      <tarfileset dir=".">
        <include name="my_file1.txt"/>
        <include name="my_file2.txt"/>
      </tarfileset>
    </tar>
  </target>
 
</project>

Note: Don't use base="." attribute in <tar> if the base directory have a directory that contains a lot of files(>50 000). Otherwise, it will be very slow, even you are not compressing that huge directory.

Run xsltproc from Ant build file

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
Description: Write a target to run xsltproc from Ant
-->
<project basedir="." default="run_xsltproc" name="run_xsltproc">
 
  <!-- Note: I explicitly use the --output option provided by xsltproc
              so that in case of error, it will show in the eclipse console. 
  -->
  <target name="run_xsltproc">
    <exec executable="xsltproc.exe" failonerror="true">
      <arg value="--xinclude"/>
      <arg value="--output" />
      <arg value="your_xml_output_file.html" />
      <arg value="your_xsl.xsl"/>
      <arg value="your_xml_input_file.xml"/>
    </exec>
  </target>
 
</project>

In case where you can't run xsltproc.exe because of issue with MSVCRT.dll and that you need to resolve XInclude, then use xmllint.exe to resolve XInclude and Saxon to process the transformation. Here is an example:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>              
  <!-- Use xmllint & Saxon because there is an issue with MSVCRT.dll for xsltproc -->
  <exec executable="xmllint" failonerror="true">
    <arg value="--xinclude"/>
    <arg value="your_xml_input_file.xml"/>
    <arg value="--output" />
    <arg value="lint.tmp.xml" />
  </exec>
 
  <java jar="lib/saxon/saxon.jar"
    output="your_xml_output_file.html"
    fork="true">
 
    <arg value="lint.tmp.xml"/>
    <arg value="your_xsl.xsl"/>
  </java>
</project>

Send email if tests failed using Ant

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--
  Here is an example of how to set Ant build file to send out 
   emails if tests failed.
-->
<project basedir="." default="run_testng" name="SendEmailExample">
 
  <!-- Your TestNG target -->
  <target name="run_testng" >
    <testng failureProperty="test.failed">
      <!-- ... your TestNG instructions here... -->
    </testng>
  </target>
 
  <!-- 
    The target sendMail will be executed only if test.failed is true. 
      test.failed value come from <testng>, see run_testng target above. 
      Therefore, email will be sent only if the test failed. 
  -->
  <target name="sendMail" if="test.failed" depends="run_testng">
    <mail mailhost="your.mail.smtp.com" mailport="25" failonerror="false"
      subject="Your subject here...">
 
      <from address="from@company.com"/>
 
      <to address="to1@company.com"/>
      <to address="to2@company.com"/>
      <to address="to3@company.com"/>
      <to address="toX@company.com"/>
 
      <message>Your message here....</message>
 
      <attachments>
        <fileset dir=".">
          <include name="filename.txt"/>
        </fileset>
      </attachments>
 
    </mail>
  </target>
</project>  

If you are adding attachments to your email and you are getting the error message "Failed to initialise MIME mail: javax/mail/MessagingException", then download JavaMail API(i.e. mail.jar) and JavaBeans Activation Framework(i.e. activation.jar) and copy them in the lib/ folder of Ant.