Home > java > Generic Apache Ant build.xml for webapps with JUnit tests

Generic Apache Ant build.xml for webapps with JUnit tests

This post is about a build.xml file for Apache Ant that compiles, unit tests and packages a typical web application. The main build artifact is a timestamped WAR file.

Standardized directory layout

The build file assumes that your project uses the following directories:

  • src : Java sources and classpath resources
  • test : JUnit test sources and classpath resources
  • web : Web resources (JSP, HTML, CSS, etc.)
  • web/WEB-INF/lib : jars required by the web application at runtime
  • devlib/provided : jars provided by the web container at runtime
  • devlib/test : jars required for test compilation or execution

Transient build directories

The build will create these transient output directories for each stage of the build process. You should configure the version control of your project to ignore them.

  • build/classes : Compiled Java code and classpath resources (compile)
  • build/test-classes : Compiled JUnit tests (test-compile)
  • build/test-reports : JUnit test reports (test)
  • dist : WAR file (dist)

Run ant clean to delete them after you grabbed the WAR file.

The build.xml file

<project name="PROJECT_NAME" default="dist">

    <property name="classes" location="build/classes"/>
    <property name="test-classes" location="build/test-classes"/>
    <property name="test-reports" location="build/test-reports"/>

    <path id="classpath">
        <fileset dir="devlib/provided">
            <include name="*.jar"/>
        <fileset dir="web/WEB-INF/lib">
            <include name="*.jar"/>

    <path id="test-classpath">
        <path refid="classpath"/>
        <pathelement location="${classes}"/>
        <pathelement location="${test-classes}"/>
        <fileset dir="devlib/test">
            <include name="*.jar"/>

    <target name="clean">
        <delete dir="dist"/>
        <delete dir="build"/>

    <target name="compile">
        <mkdir dir="${classes}"/>
        <javac destdir="${classes}">
            <classpath refid="classpath"/>
            <src path="src"/>
            <src path="common/src"/>
        <copy todir="${classes}">
            <fileset dir="src" excludes="**/*.java"/>

    <target name="test-compile" depends="compile">
        <mkdir dir="${test-classes}"/>
        <javac destdir="${test-classes}">
            <src path="common/test"/>
            <src path="test"/>
            <classpath refid="test-classpath"/>

    <target name="test" depends="test-compile">
        <mkdir dir="${test-reports}"/>
        <junit printsummary="yes">
            <classpath refid="test-classpath"/>
            <formatter type="brief" usefile="false"/>
            <formatter type="xml"/>
            <batchtest todir="${test-reports}" failureproperty="failed"
                <fileset dir="${test-classes}" includes="**/*Test.class"/>

        <format property="timestamp" pattern="yyyy-MM-dd_hh-mm"/>

    <target name="dist" depends="clean, compile, test">
        <mkdir dir="dist"/>
        <war destfile="dist/${ant.project.name}_${timestamp}.war"
            <classes dir="${classes}"/>

Categories: java Tags: , ,
  1. Alan Krueger
    October 5, 2012 at 19:02

    I notice that this is 71 lines long. You can basically accomplish the same thing with a one-line Gradle build script. (http://www.gradle.org/docs/current/userguide/tutorial_java_projects.html#N103D9)

    • October 7, 2012 at 08:39

      That is interesting, Alan. Thanks for the link.

      However, I wrote this article for folks like me who currently have to use Ant for webapp projects because the customer has chosen Ant as the “standard” build tool …

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: