2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

Ant Integration

Cactus provides strong integration with the popular build tool Ant. This integration consists of a handful of tasks that support the running of tests from an Ant build file.


A strong principle of eXtreme Programming (XP) is the continuous integration aspect (see the Continuous Integration article by Martin Fowler). The traditional approach to the development of complex software has been to separate the development process into phases of coding, testing and integration. The continuous integration principle is to basically code, test and integrate at the same time, so that at almost any point in time, you have a working product.

In order to achieve this, you need to be able to automatically build your entire application, including running the unit and acceptance tests. Thus, tools such as Ant or Maven are the foundation for continuous integration. You can build on that foundation by using a dedicated continuous integration tool like CruiseControl, Gump or AntHill.

Ant is written in Java and provides a wide variety of tasks that support the development of Java applications (though it is in no way restricted to development). In addition, many third-party tasks are available, and it is quite easy to extend Ant with custom tasks.

Ant Resources

This documentation assumes good knowledge of the basic concepts of Ant. Here are several resources that can help you get up to speed if you haven't been using Ant yet:

  • The Ant Manual is the definitive source about Ant.
  • Ant in Anger discusses best practices and common pitfalls with Ant usage.
  • The book Java Development With Ant by Erik Hatcher and Steve Loughran is very much recommended if you plan to use Ant intensively.
  • The document The Elements of Ant Style in the Apache Wiki lists some general rules for using Ant effectively in any kind of project.
A full list of resources is maintained by the Ant team at http://ant.apache.org/resources.html

Installing the Cactus Ant Tasks

The Ant tasks provided by Cactus are distributed together with the main distribution of Cactus, which you can get from the download area. After downloading and expanding the archive, you'll find several JAR files in the lib directory. See the Classpath Guide for information about which of the JARs you need for what. It is recommended that you copy these JARs into the project for which you are writing Cactus tests. A common pattern is to have a lib directory in the project directory, and put all the JARs there.

WARNING!: Since Cactus 1.8 you need the two cargo-ant.jar and cargo-uberjar.jar jars in your classpath, since cactus relies on the cargo project.

So your project might look something like this:
  [your project]
    |- doc
    |  ...
    |- lib
    |   |- cactus.core.framework.uberjar.<VERSION>.jar
    |   |- cactus.integration.shared.api.<VERSION>.jar
    |   |- cactus.integration.ant.<VERSION>.jar
    |   |- cactus-ant.jar
    |   |- commons-httpclient.jar
    |   |- commons-logging.jar
    |   |- junit.jar
    |   |- aspectjrt.jar
    |   |- cargo-ant.jar
    |   |- cargo-uberjar.jar
    |- src
    |   |- java
    |   |  ...
    |   |- test
    |   |  ...
    |- build.xml

Of course, you can put them anywhere you want as long as you can correctly locate them from within your build file. Another option is to put all the libraries in the lib directory of your Ant installation, so that they get added to the classpath automatically. This option is not recommended, however, as it quickly leads to pollution of the classpath used by Ant.

There's one step left to enable your project to run Cactus tests from within Ant: you'll need to introduce the Cactus tasks to Ant. This is done with a <taskdef>:

<!-- Define the Cactus tasks -->
<taskdef resource="cactus.tasks">
    <pathelement location="lib/cactus.core.framework.uberjar.<VERSION>.jar"/>
    <pathelement location="cactus.integration.shared.api.<VERSION>.jar"/>
    <pathelement location="cactus.integration.ant.<VERSION>.jar"/>
    <pathelement location="cargo-ant.jar"/>
    <pathelement location="cargo-uberjar.jar"/>
    <pathelement location="lib/commons-httpclient.jar"/>
    <pathelement location="lib/commons-logging.jar"/>
    <pathelement location="lib/aspectjrt.jar"/>

As you can see, you'll need to add the JARs required by Cactus to the <classpath> of the task definition. Note that we don't include the JUnit library, because it usually needs to be installed in the lib directory of your Ant installation (see the Ant FAQ for details).

If you get an error at this point, make absolutely sure that you've correctly set up the classpath for the task definition. Run Ant with the -verbose or the -debug options to find out which libraries or classes could not be found, or what else may be going wrong.

Using the Cactus Ant Tasks

After you have defined the Cactus tasks you'll need to actually use them in the build file to run the Cactus tests. Cactus provides a couple of tasks that support you with running the tests from an Ant build. Each of the tasks is independant or complementary to the others. You'll need to decide on what tasks to used depending on your requirements.

Ant tasks provided by Cactus
CactifyWar This task can enhance a provided web application archive (WAR), and add the elements required to run Cactus tests against it. This includes the JARs required by Cactus on the server-side, as well as the definitions of the test redirectors in the deployment descriptor.
CactifyEar This task can enhance a provided Enterprise application archive (EAR), and add the elements required to run Cactus tests against it. It can also add EJB references to allow testing of local EJB:s.
Cactus This task extends the standard <junit> task with the capability of running in-container tests.
RunServerTests This task is an alternative to the <cactus> task that is more generic but harder to use. In contrast to the <cactus> task, it is not an extension of the standard <junit> task.
WebXmlMerge This task can merge the definitions from two web deployment descriptors into a new descriptor, and can thus be used to add the definition of the Cactus redirectors to an existing descriptor. The same functionality is provided by the <cactifywar> task, so if you want to cactify an entire WAR, you should use that task instead.

Typically, the sequence for executing Cactus tests from an Ant build will be the following:

  1. Compile the test classes (using the standard tasks like <javac>)
  2. Cactify the web-application (using the <cactifywar> task, or the <webxmlmerge> task in combination with builtin Ant tasks like <war> and <unwar>)
  3. Start the target container, deploy the application, run the tests and stop the container (using either <cactus> or <runservertests>)