Apache Ant organizes Java build automation into named targets with dependency chains. This guide is for engineers maintaining legacy or lightweight Java build systems, and it shows exactly how a clean → prepare → compile flow works, how to run it, and what to watch for in real projects.
Originally published on 2010-07-22; fully revised and updated.

What the clean, prepare, and compile targets do
This pattern separates build responsibilities into predictable stages:
- clean: removes previously generated output.
- prepare: recreates required directory structure.
- compile: compiles application and test sources using a shared classpath.
Because Ant supports target dependencies, running compile automatically triggers prepare, which in turn triggers clean.
Build dependency workflow
The dependency chain below reflects the original logic and execution order.
flowchart TD
A[Run ant compile] --> B[clean target]
B --> C[Delete output and temp directories]
C --> D[prepare target]
D --> E[Create build directories]
E --> F[compile target]
F --> G[Compile src.dir sources]
G --> H[Compile src.tests.dir subset]
H --> I[Classes ready in temp.dir.classes]
Complete build.xml example
The original post showed core targets only. The example below keeps that logic and adds the minimal surrounding properties and classpath so it can be used as a practical template.
<project name="sample-build" default="compile" basedir=".">
<property name="src.dir" value="src" />
<property name="src.tests.dir" value="src-tests" />
<property name="dest.dir" value="build/dist" />
<property name="temp.dir" value="build/tmp" />
<property name="temp.dir.lib" value="${temp.dir}/lib" />
<property name="temp.dir.meta-inf" value="${temp.dir}/META-INF" />
<property name="temp.dir.web-inf" value="${temp.dir}/WEB-INF" />
<property name="temp.dir.classes" value="${temp.dir}/classes" />
<property name="lib.dir" value="lib" />
<path id="build.class.path">
<fileset dir="${lib.dir}" includes="**/*.jar" />
</path>
<target name="clean">
<echo>=== CLEAN ===</echo>
<delete failonerror="false">
<fileset dir="${dest.dir}" includes="**/*" />
</delete>
<delete dir="${temp.dir}" />
</target>
<target name="prepare" depends="clean">
<echo>=== PREPARE ===</echo>
<mkdir dir="${dest.dir}" />
<mkdir dir="${temp.dir}" />
<mkdir dir="${temp.dir.lib}" />
<mkdir dir="${temp.dir.meta-inf}" />
<mkdir dir="${temp.dir.web-inf}" />
<mkdir dir="${temp.dir.classes}" />
</target>
<target name="compile" depends="prepare">
<echo>=== COMPILE ===</echo>
<echo>Compiling ${src.dir} files ...</echo>
<javac debug="on" srcdir="${src.dir}" destdir="${temp.dir.classes}" includes="**/*.java">
<classpath refid="build.class.path" />
</javac>
<!-- Compile selected test sources -->
<echo>Compiling ${src.tests.dir} files ...</echo>
<javac debug="on" srcdir="${src.tests.dir}" destdir="${temp.dir.classes}" includes="com/**/*.java">
<classpath refid="build.class.path" />
</javac>
</target>
</project>Code language: HTML, XML (xml)
Target comparison
| Target | Depends on | Main purpose | Key operations |
|---|---|---|---|
| clean | None | Remove prior build output | Delete ${dest.dir} contents and ${temp.dir} |
| prepare | clean | Create a known directory layout | Create destination, temp, classes, and metadata folders |
| compile | prepare | Compile source code | Run javac for main and selected test sources using build.class.path |
How to run these targets
From the directory containing build.xml:
ant clean
ant prepare
ant compile
In day-to-day use, ant compile is usually enough because dependencies execute upstream targets automatically.
Best practices
- Keep target responsibilities narrow: cleanup, setup, and compilation should stay separate.
- Prefer explicit include patterns like
**/*.javafor predictable compilation scope. - Define all referenced properties and path IDs in one place near the top of
build.xml. - Be intentional about test output location; compiling tests into the same classes directory can blur boundaries.
- Use dependency chains instead of repeated commands so the build remains deterministic.
I’m Rajesh Kumar, a DevOps, SRE, DevSecOps, Cloud, and Platform Engineering expert passionate about sharing practical knowledge, real-world experiences, and industry best practices. I have worked at Cotocus and regularly write about technology, travel, investing, health, product reviews, and digital marketing through my various platforms.
I publish technical articles at DevOps School, travel stories at Holiday Landmark, stock market insights at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow, and SEO and digital marketing strategies at Wizbrand.
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services — all in one place.
Explore Hospitals
Apache Ant Comments and echo Task: Write Clear build.xml Files and Control Log Output
Learn the correct way to add comments in Apache Ant and when to use the echo task instead. This guide covers echo attributes, log-level behavior, and practical build.xml examples.