Last Modified on 25 Aug 2004

This tutorial is a collection of information about using JavaScript and XSLT with Ant and is focused on intermediate to expert client-side web developers. It is presently a very rough draft.

Information in this tutorial was taken from several sources including the ant-user mailing list and the ant manual. Where possible, the date and location of the source material have been noted to provide credit to members of the community and to aid in your search for more information. If there is any material in this tutorial that is not public or is copyrighted please contact the authors of this tutorial and this information will be removed.

All e-mail addresses in this document have been munged in an attempt to block spam spiders. Replace [at] with the @ symbol to un-munge the address.

Warning and Disclaimer: No guarantee exists that this tutorial is correct, up to date, or even harmless.

This tutorial is copyrighted and is provided as a resource for the open source community. In that spirit, it is freely available to be copied, mirrored, modified, and taken for your own use provided that full credit is given to the authors and Ant community in all redistributions and derivative works.

—Dylan Schiemann on 14 Feb 2002

What is Ant?

Apache Ant is a build based tool. It has a vast array of uses for programmers. Often overlooked is its usefulness for client-side web developers. It is especially useful for preprocessing tokens across many pages of a website, rather than relying on SSI, PHP, ASP, or JSP. It is also very useful for building a site with an XSLT processor such as Xalan. If you are not familiar with Ant, be sure to read the ant manual which has instructions for installing and using Ant.

Why JavaScript in Ant?

Ant does not have standard commands for programming techniques like recursion. Instead, it contains prebuilt tasks for using your language of choice. JavaScript is an easy to use, widely known scripting language and is easily added to Ant through its optional tasks.

Adding JavaScript to Ant

Download the optional task jar from the ant website, the bsf.jar, and rhino.jar from Mozilla (rename js.jar to rhino.jar). Include these jars in your class path. Note that some of the examples described here do not work effectively with older versions of Ant. There are also issues with mixing older and newer versions of BSF and Ant.

Adding XSLT to Ant

To include an XSLT processor such as Xalan-J-2, you will also need to download and configure it. You will also need to add the location of your Xalan jars to your Ant classpath or make a copy of the necessary jars.

Hello World Example

The obligatory hello world example simply echos Hello World to Ant’s generated results

<project name="helloWorld" default="main" basedir=".">

<target name="setup">

<script language="javascript"> <![CDATA[

        echo = helloWorld.createTask("echo");
        main.addTask(echo);
        echo.setMessage("Hello World!");

    ]]> </script>

</target>

<target name="main" depends="setup"/>

</project>

generates:

setup:

main:
Hello World!

BUILD SUCCESSFUL

To include JavaScript within Ant, you use a script tag much as you do in any XML document. To define the Script language, use the older language declaration rather than the newer type syntax. You may also use a src attribute to include an external script.

Ant Manual Script Task on 11 Feb 2002

General Objects

To do more interesting things with Ant, you have access to properties, targets, and references. For an explanation of properties, targets, and references, refer to the ant manual

project.getProperty(string propertyName);
project.getUserProperty(string propertyName);
project.getTarget(string targetId);
project.getReference(string refereceId);

project is a shortcut for getProject(), which returns the project object.
self returns the script task itself for logging and other task specific utilities.

If you have two things with the same name/id, only the last one in the document order is used. Illegal Java names cause it to be omitted.

—Erik Hatcher (jakarta-ant[at]ehatchersolutions.com) on 12 Feb 2002

XSLT Task

To use the standard XSLT task, with a single input and output file, and to pass a parameter to the stylesheet, you could do the following in your build file:

<style in="src/webProject.xml" out="temp/index.html"
	extension="html" style="webSite.xsl" processor="trax">
 <param name="pageId" expression="com.sitepen.pages.home"/>
</style>

To process an entire directory of documents, you could do the following:

<style basedir="." destdir="temp"
       extension="html" style="style/webSite.xsl"/>

Ant Manual Style Task on 11 Feb 2002

However, lost is the ability to pass a different parameter for each generated document. This is where I found JavaScript to be particularly useful, as shown in this example:

<project name="siteBuilder" default="deploy" basedir=".">

   <target name="init">
      <property name="runDir" value="." />
      <property name="varsDir" value="vars" />

      <property name="sourceDir" value="src" />
      <property name="outputDir" value="www" />
      <property name="tempDir" value="temp" />

      <property name="tokenValues" value="tokenValues.properties" />


      <property file="${varsDir}/${tokenValues}" />

   </target>

   <target name="clean" depends="init">

      <delete includeEmptyDirs="true" >
          <fileset dir="${outputDir}" />
      </delete>
   </target>

   <target name="prepare" depends="clean">
      <mkdir dir="${outputDir}" />

   </target>

   <target name="compile" depends="prepare">

      <copy todir="${tempDir}">

         <fileset dir="${sourceDir}">
            <exclude name="**/*.html"/>

         </fileset>
      </copy>

   <script language="javascript">
      <![CDATA[
      importClass(java.io.File)
	xslt = siteBuilder.createTask("style");
	runDirectory = siteBuilder.getProperty("runDir");
	tempDirectory = siteBuilder.getProperty("tempDir");
	inFile = new File(runDirectory + "/webProject.xml");
	outFile = new File(tempDirectory+"/index.html");
	xslt.setStyle("webSite.xsl");
	xslt.setIn(inFile);
	xslt.setOut(outFile);
	xslt.setProcessor("trax");
	idParameter = xslt.createParam();
	idParameter.setName("pageId");
	idParameter.setExpression("com.sitepen.pages.home");
	xslt.execute();

      ]]>

   </script>

   </target>

   <target name="deploy" depends="compile,init">
      <copy todir="${outputDir}">
         <fileset dir="${tempDir}">

            <exclude name="**/*.xml"/>

         </fileset>
      </copy>
      <delete includeEmptyDirs="true" >
          <fileset dir="${tempDir}" />
      </delete>

   </target>

</project>

—Dylan Schiemann on 14 Feb 2002

Using JavaScript to recurse over a properties file

*** I am presently unable to get this to work as it seems that property files only work with tasks that use tokens ***

Looping through tasks

Ant does not have a built-in looping mechanism, so many people use JavaScript to accomplish this. For example, to create a series of directories, you could do the following:

   <script language="javascript">
      <![CDATA[
         importClass(java.io.File); //Java class needed for file creation
         var directoryNames = new Array();
         directoryNames[0] = "directoryName0";
         directoryNames[1] = "directoryName1";
         directoryNames[2] = "directoryName2";
         // ... and so on
         // in this example, the directory path is stored as part of the directory name.
         for (i=0;i<directoryNames.length;i++)
         {
            // projectName is the name of your project
            makeDirectory = projectName.createTask("mkdir");
            directory = new File(directoryNames[i]);
            makeDirectory.setDir(directory);
            makeDirectory.execute();
         }

      ]]>
   </script>

—based on example by Diane Holt on 25 Sep 2001