Skip to content

Apache Ant Cheatsheet

Installation

Platform Command
Ubuntu/Debian sudo apt update && sudo apt install ant
RHEL/CentOS/Fedora sudo yum install ant or sudo dnf install ant
Arch Linux sudo pacman -S apache-ant
macOS (Homebrew) brew install ant
Windows (Chocolatey) choco install ant
Manual (All Platforms) Download from apache.org, extract, set ANT_HOME and add bin/ to PATH

Prerequisites: Java JDK 8+ required. Set JAVA_HOME environment variable.

Basic Commands

Command Description
ant -version Display Ant version, Java version, and OS information
ant Execute default target specified in build.xml
ant compile Run the "compile" target from build.xml
ant clean Run the "clean" target (typically removes build artifacts)
ant -projecthelp List all available targets with descriptions
ant -p Short form of -projecthelp
ant -f custom-build.xml Use alternative build file instead of build.xml
ant -buildfile mybuild.xml compile Specify build file and target to execute
ant -verbose compile Show detailed execution information
ant -v test Short form of -verbose
ant -debug package Maximum verbosity for troubleshooting
ant -d deploy Short form of -debug
ant -quiet test Minimal output, only show errors
ant -q build Short form of -quiet
ant -logfile build.log compile Redirect output to specified log file
ant -l output.log test Short form of -logfile

Advanced Usage

Command Description
ant -Denv=production deploy Set property value at command line
ant -Dversion=1.2.3 -Dbuild.number=456 package Set multiple properties
ant -propertyfile custom.properties build Load properties from external file
ant -find Search parent directories for build.xml
ant -s Short form of -find
ant -keep-going test Continue executing independent targets after failure
ant -k test Short form of -keep-going
ant -diagnostics Display system information and configuration details
ant -listener org.apache.tools.ant.listener.Log4jListener compile Add custom build event listener
ant -logger org.apache.tools.ant.NoBannerLogger compile Use custom logger implementation
ant -inputhandler org.apache.tools.ant.input.SecureInputHandler deploy Use custom input handler for secure input
ant -noclasspath compile Ignore CLASSPATH environment variable
ant -autoproxy download Automatically configure Java proxy settings
ant -lib /path/to/jars compile Add directory of JARs to Ant's classpath
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor build Enable parallel task execution
ant compile test package Execute multiple targets in sequence
ant -Dskip.tests=true package Conditionally skip tasks based on property

Configuration

Basic build.xml Structure

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="build" basedir=".">

    <!-- Properties -->
    <property name="src.dir" value="src"/>
    <property name="build.dir" value="build"/>
    <property name="dist.dir" value="dist"/>
    <property name="lib.dir" value="lib"/>

    <!-- Classpath -->
    <path id="classpath">
        <fileset dir="${lib.dir}">
            <include name="**/*.jar"/>
        </fileset>
    </path>

    <!-- Clean target -->
    <target name="clean" description="Remove build artifacts">
        <delete dir="${build.dir}"/>
        <delete dir="${dist.dir}"/>
    </target>

    <!-- Init target -->
    <target name="init" depends="clean">
        <mkdir dir="${build.dir}"/>
        <mkdir dir="${dist.dir}"/>
    </target>

    <!-- Compile target -->
    <target name="compile" depends="init" description="Compile source code">
        <javac srcdir="${src.dir}" 
               destdir="${build.dir}"
               classpathref="classpath"
               includeantruntime="false"
               debug="true"
               source="11"
               target="11"/>
    </target>

    <!-- Build target -->
    <target name="build" depends="compile" description="Build JAR file">
        <jar destfile="${dist.dir}/${ant.project.name}.jar" 
             basedir="${build.dir}">
            <manifest>
                <attribute name="Main-Class" value="com.example.Main"/>
            </manifest>
        </jar>
    </target>

</project>

build.properties File

# Project configuration
project.name=MyApplication
project.version=1.0.0

# Directory structure
src.dir=src/main/java
test.dir=src/test/java
resources.dir=src/main/resources
build.dir=target/classes
dist.dir=dist

# Compiler settings
java.source.version=11
java.target.version=11
javac.debug=true
javac.deprecation=true

# Dependencies
lib.dir=lib

Loading Properties in build.xml

<property file="build.properties"/>
<property file="build-${env}.properties"/>
<property environment="env"/>

Common Filesets and Patterns

<!-- Include all Java files -->
<fileset dir="${src.dir}" includes="**/*.java"/>

<!-- Exclude test files -->
<fileset dir="${src.dir}">
    <include name="**/*.java"/>
    <exclude name="**/*Test.java"/>
</fileset>

<!-- Pattern sets for reuse -->
<patternset id="source.patterns">
    <include name="**/*.java"/>
    <include name="**/*.properties"/>
    <exclude name="**/*Test.java"/>
</patternset>

Common Use Cases

Use Case: Complete Java Application Build

# Clean previous builds
ant clean

# Compile, test, and package in one command
ant compile test package

# Build with specific environment properties
ant -Denv=production -propertyfile prod.properties package

# Create distribution with documentation
ant clean compile test package javadoc dist

build.xml targets:

<target name="test" depends="compile">
    <junit printsummary="yes" haltonfailure="yes">
        <classpath>
            <path refid="classpath"/>
            <pathelement location="${build.dir}"/>
        </classpath>
        <batchtest fork="yes">
            <fileset dir="${test.dir}">
                <include name="**/*Test.java"/>
            </fileset>
        </batchtest>
    </junit>
</target>

<target name="javadoc">
    <javadoc sourcepath="${src.dir}" 
             destdir="${dist.dir}/docs"
             packagenames="com.example.*"/>
</target>

Use Case: WAR File Creation for Web Application

# Build and package web application
ant clean compile war

# Deploy to application server
ant -Dserver.path=/opt/tomcat/webapps deploy

build.xml configuration:

<target name="war" depends="compile">
    <war destfile="${dist.dir}/${project.name}.war" 
         webxml="web/WEB-INF/web.xml">
        <classes dir="${build.dir}"/>
        <lib dir="${lib.dir}"/>
        <fileset dir="web">
            <include name="**/*.jsp"/>
            <include name="**/*.html"/>
            <include name="**/*.css"/>
            <include name="**/*.js"/>
        </fileset>
    </war>
</target>

<target name="deploy" depends="war">
    <copy file="${dist.dir}/${project.name}.war" 
          todir="${server.path}"/>
</target>

Use Case: Multi-Module Project Build

# Build all modules in parallel
ant -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor build-all

# Build specific module
ant -Dmodule=core build-module

# Build and run integration tests
ant build-all integration-test

build.xml with subprojects:

<target name="build-all">
    <subant target="build">
        <fileset dir="." includes="*/build.xml"/>
    </subant>
</target>

<target name="build-module">
    <ant dir="${module}" target="build" inheritAll="false"/>
</target>

Use Case: Conditional Builds with Property Checking

# Skip tests during build
ant -Dskip.tests=true package

# Build only if sources changed
ant -Dincremental=true compile

# Production build with optimizations
ant -Doptimize=true -Ddebug=false production-build

build.xml with conditions:

<target name="compile">
    <javac srcdir="${src.dir}" 
           destdir="${build.dir}"
           debug="${debug}"
           optimize="${optimize}">
        <classpath refid="classpath"/>
    </javac>
</target>

<target name="test" unless="skip.tests">
    <junit printsummary="yes">
        <classpath>
            <path refid="classpath"/>
            <pathelement location="${build.dir}"/>
        </classpath>
        <batchtest>
            <fileset dir="${test.dir}" includes="**/*Test.java"/>
        </batchtest>
    </junit>
</target>

<target name="package" depends="compile,test">
    <jar destfile="${dist.dir}/${ant.project.name}.jar" 
         basedir="${build.dir}"/>
</target>

Use Case: Database Migration and Deployment

# Run database migrations
ant -propertyfile db-config.properties db-migrate

# Deploy application with database updates
ant -Denv=staging db-migrate deploy

# Rollback database changes
ant -Dversion=1.2.0 db-rollback

build.xml with SQL tasks:

<target name="db-migrate">
    <sql driver="${db.driver}"
         url="${db.url}"
         userid="${db.user}"
         password="${db.password}"
         src="migrations/migrate-${version}.sql"
         print="yes"
         output="migration.log"/>
</target>

<target name="db-rollback">
    <sql driver="${db.driver}"
         url="${db.url}"
         userid="${db.user}"
         password="${db.password}"
         src="migrations/rollback-${version}.sql"/>
</target>

Best Practices

  • Use property files for configuration: Separate environment-specific settings from build logic. Load properties with <property file="build.properties"/> to keep build.xml clean and reusable.

  • Define meaningful target descriptions: Add description attributes to public targets for better ant -projecthelp output. This serves as built-in documentation for your build process.

  • Leverage target dependencies: Use depends attribute to establish build order and avoid redundant task execution. Ant automatically handles dependency resolution.

  • Set includeantruntime="false" in javac tasks: Prevents Ant runtime libraries from polluting your application classpath, avoiding potential conflicts and reducing JAR size.

  • Use filesets and pattern sets for flexibility: Define reusable file patterns with <patternset> and reference them in multiple targets. This makes maintenance easier and reduces duplication.

  • Implement incremental builds: Use <uptodate> conditions to skip compilation when source files haven't changed, significantly speeding up development builds.

  • Version control your build files: Include build.xml, property files, and custom tasks in version control. Exclude generated directories like build/ and dist/ using .gitignore.

  • Use macros for repeated task sequences: Define <macrodef> elements for common operations performed across multiple modules or targets, promoting DRY principles.

  • Separate concerns with imported build files: Split large build files into logical components (common-build.xml, test-build.xml) and import them to improve maintainability.

  • Document complex logic with comments: Use XML comments to explain non-obvious build logic, property usage, and dependencies, especially in shared or legacy projects.

Troubleshooting

Issue Solution
BUILD FAILED: build.xml does not exist Run ant -find to search parent directories, or specify file with ant -f path/to/build.xml
Unable to locate tools.jar Set JAVA_HOME to JDK (not JRE) directory. Verify with echo $JAVA_HOME and ensure it points to JDK installation
ClassNotFoundException for custom tasks Add JAR to Ant's classpath using -lib option: ant -lib /path/to/jars compile or use <taskdef> with correct classpath
Compilation fails with encoding errors Add encoding="UTF-8" attribute to <javac> task: <javac srcdir="${src.dir}" encoding="UTF-8"/>
Out of memory during build Increase heap size: export ANT_OPTS="-Xmx1024m -Xms512m" (Linux/Mac) or set ANT_OPTS=-Xmx1024m (Windows)
Target not found error Verify target name with ant -projecthelp. Check for typos and ensure target is defined in active build file
Circular dependency detected Review depends attributes in targets. Ant cannot resolve circular references - redesign target dependencies
Permission denied when writing files Check directory permissions and ensure Ant has write access. Run with appropriate user privileges or adjust directory ownership
fork="true" required but task fails Some tasks (junit, java) require forking. Ensure fork="true" is set and JAVA_HOME points to valid JDK
Properties not being overridden Properties are immutable in Ant - first definition wins. Set properties via command line (-D) before build file loads them
Slow builds with large filesets Use <uptodate> conditions for incremental builds. Enable parallel execution with -Dant.executor.class=org.apache.tools.ant.helper.ParallelExecutor
JAR file manifest not correct Use <manifest> element within <jar> task to specify Main-Class and other attributes explicitly

Common Ant Tasks Reference

Task Description Example
<javac> Compile Java source files <javac srcdir="src" destdir="build" includeantruntime="false"/>
<jar> Create JAR archive <jar destfile="dist/app.jar" basedir="build"/>
<war> Create WAR archive <war destfile="dist/app.war" webxml="web/WEB-INF/web.xml"/>
<copy> Copy files or directories <copy todir="backup"><fileset dir="src"/></copy>
<delete> Delete files or directories <delete dir="build"/>
<mkdir> Create directory <mkdir dir="dist"/>
<echo> Print message <echo message="Building version ${version}"/>
<exec> Execute system command <exec executable="git" args="rev-parse HEAD"/>
<junit> Run JUnit tests <junit printsummary="yes" fork="yes"/>
<zip> Create ZIP archive <zip destfile="dist/src.zip" basedir="src"/>
<sql> Execute SQL statements <sql driver="${db.driver}" url="${db.url}" src="schema.sql"/>
<get> Download file from URL <get src="http://example.com/lib.jar" dest="lib/"/>