When Ant is subsidiary to <oXygen/>

The <oXygen/> documentation has an example of setting up an “External Tool” to run Ant. The example is simple enough to illustrate its point, but there’s more that can be done, especially if you write the Ant build file knowing that it will be run from <oXygen/>.

This example is from the <oXygen/> “project” that I used for organising the exercises for my “Testing XSLT” tutorial at XTech 2008. The tutorial exercises included using <oXygen/> as one of three ways to profile XSLT stylesheets, but I set up an <oXygen/> project that includes the XML and XSLT files for all exercises, too, so things would ‘just work’ (a useful feature considering the tutorial was allocated half the time originally proposed). The project included several “External Tool” definitions, including several for running Ant. This example is the setup for an external tool for running the Tennison Tests XSLT unit testing framework:

External tool definition

The complete command line is:

java -Dant.home=${pd}/apache-ant-1.7.0
-cp ${pd}/apache-ant-1.7.0/lib/ant-launcher.jar:${oxygenInstallDir}/lib/saxon9.jar
org.apache.tools.ant.launch.Launcher -f ${pd}/build-tennison-tests.xml -Dpd=${pd} test

Extensions beyond the necessarily simple example in the <oXygen/> documentation include:

  • Using an “Editor variable” for the working directory. Using ${cfd} executes the command in the directory of the current file, but you could also use the project directory (${pd}), your home directory (${home}), or the <oXygen/> installation directory (${oxygenInstallDir}, though it’s likely you can’t and/or won’t want to create files there).
  • Running Ant (nearly) independently of the operating system. The documentation example uses ant.bat, which is fine for Windows users, but I didn’t know which operating systems the people would be using. Running Ant via Java works the same way for all platforms unless you need more than one jar file in the classpath. With multiple jars, you need the OS-specific path separator (‘:’ for Unix/Linux, ‘;’ for Windows), so I had to make a Windows-specific version of this external tool that was identical except for the path separator. (Note that Ant is located relative to the project directory in this example because I included Ant in the software bundle for the exercises, again because I couldn’t be sure what the attendees already had installed.)
  • Using jars from the <oXygen> lib directory. This usefully saved me from having to install additional copies of the jars and, if you’re being maximally <oXygen/>-centric, it ensures that you get consistent results whether running the same transform in <oXygen/>’s debugger, profiler, or transformation scenarios or in the external tool.
  • Locating the build file relative to the project directory. The -f ${pd}/build-tennison-tests.xml makes Ant use that particular build file (out of several) in the project directory, irrespective of the current working directory.
  • Using <oXygen/> editor variables in the Ant build file. The -Dpd=${pd} defines an Ant ${pd} variable that has the same value as the <oXygen/> ${pd} editor variable. This value defined on the command line overrides the default value set in the build file. You can do the same for as many of the <oXygen/> editor variables as you need; for example, you could use ${oxygenInstallDir} when you want to use jars from <oXygen/>’s libdirectory in classpaths in Ant. The other thing you need to do is define the variables in the Ant build file, e.g.:
    <!-- <oXygen/>-related properties. -->
    <property name="pd" value="."/>
    <property name="cfd" value="."/>

The build file is still usable outside <oXygen/>. In the ordinary case, you would have Ant installed in a common location (rather than one copy per project) and would have the ant executable on your path. Since my ordinary Ant has Saxon in its classpath, I can run the same command in the project directory as:

ant -f build-tennison-tests.xml test

or from any other directory (for slightly more effort) as:

ant -f path/to/pd/build-tennison-tests.xml -Dpd=path/to/pd test