Apache Ant is a target-driven build tool that is still widely encountered in legacy Java EE (historically called J2EE) environments. This guide is for engineers who need to maintain, troubleshoot, or standardize Ant-based enterprise builds, with a clear workflow, practical commands, and reusable configuration examples.
Originally published on 2010-03-21; fully revised and updated.
Original presentation and attribution
The original post was primarily a slide embed. Source links preserved here: original article permalink, Using Ant To Build J2 Ee Applications, and author profile Rajesh Kumar.

What Ant typically handles in a J2EE build
In enterprise Java projects, Ant usually orchestrates repeatable steps from source code to deployable artifacts. A typical Ant file (build.xml) defines targets and dependencies between those targets.
- Clean old build outputs
- Compile Java sources with explicit classpaths
- Assemble WAR files for web modules
- Assemble JAR modules (for example, EJB-related classes)
- Package EAR files for application server deployment
- Copy artifacts to a deployment directory or handoff location
Reference workflow for an Ant-based J2EE pipeline
This is a practical flow you can adapt for CI jobs or local builds.
flowchart TD
A[Developer updates source] --> B[ant clean]
B --> C[ant compile]
C --> D[ant test]
D --> E{Tests pass}
E -- no --> F[Fix code and rerun]
E -- yes --> G[ant war]
G --> H[ant ear]
H --> I[Publish artifact to app server]
Suggested project layout and properties
Keep paths centralized in build.properties so environment changes do not require editing build.xml.
inventory-app/
├── build.xml
├── build.properties
├── lib/
├── src/main/java/
├── src/main/webapp/
├── src/main/config/META-INF/application.xml
├── build/
└── dist/
app.name=inventory-app
java.version=1.8
src.dir=src/main/java
web.dir=src/main/webapp
conf.dir=src/main/config
lib.dir=lib
build.dir=build
classes.dir=build/classes
dist.dir=dist
deploy.dir=/opt/appserver/autodeployCode language: JavaScript (javascript)
Example build.xml for compile, WAR, EAR, and deploy
The example below shows a conventional Ant target chain. Adapt module paths and packaging rules to your real application structure.
<project name='inventory-app' default='ear' basedir='.'>
<property file='build.properties'/>
<path id='compile.classpath'>
<fileset dir='${lib.dir}'>
<include name='**/*.jar'/>
</fileset>
</path>
<target name='clean'>
<delete dir='${build.dir}'/>
<delete dir='${dist.dir}'/>
</target>
<target name='init'>
<mkdir dir='${classes.dir}'/>
<mkdir dir='${dist.dir}'/>
</target>
<target name='compile' depends='init'>
<javac srcdir='${src.dir}'
destdir='${classes.dir}'
source='${java.version}'
target='${java.version}'
includeantruntime='false'
classpathref='compile.classpath'/>
</target>
<target name='war' depends='compile'>
<war destfile='${dist.dir}/${app.name}.war' webxml='${web.dir}/WEB-INF/web.xml'>
<fileset dir='${web.dir}'>
<exclude name='WEB-INF/web.xml'/>
</fileset>
<classes dir='${classes.dir}'/>
<lib dir='${lib.dir}'/>
</war>
</target>
<target name='ejb-jar' depends='compile'>
<jar destfile='${dist.dir}/${app.name}-ejb.jar'>
<fileset dir='${classes.dir}'>
<include name='**/ejb/**/*.class'/>
</fileset>
</jar>
</target>
<target name='ear' depends='war,ejb-jar'>
<ear destfile='${dist.dir}/${app.name}.ear' appxml='${conf.dir}/META-INF/application.xml'>
<fileset dir='${dist.dir}'>
<include name='${app.name}.war'/>
<include name='${app.name}-ejb.jar'/>
</fileset>
</ear>
</target>
<target name='deploy' depends='ear'>
<copy file='${dist.dir}/${app.name}.ear' todir='${deploy.dir}' overwrite='true'/>
</target>
</project>Code language: HTML, XML (xml)
Common Ant commands you can run
# List available targets
ant -p
# Clean and build from scratch
ant clean ear
# Build only the web archive
ant war
# Deploy to a specific directory at runtime
ant deploy -Ddeploy.dir=/srv/appserver/autodeployCode language: PHP (php)
Ant vs Maven vs Gradle in enterprise Java builds
| Tool | Build style | Dependency management | Best for | Typical trade-off |
|---|---|---|---|---|
| Ant | Imperative XML targets and task flow | Manual classpath or add-ons such as Ivy | Legacy systems and highly customized build steps | More boilerplate and convention must be maintained by the team |
| Maven | Convention-driven lifecycle with POM | Built-in repository model | Standardized Java project structure and repeatable enterprise builds | Less flexible when workflows are unusual |
| Gradle | Declarative plus programmable DSL | Built-in repository support | Large multi-module builds needing flexibility and performance tuning | Higher DSL complexity for new maintainers |
Common pitfalls and best practices
- Keep environment values externalized: use
build.propertiesand runtime-Doverrides for server-specific paths. - Make targets composable: separate
clean,compile,war,ear, anddeployso CI can call only what it needs. - Fail early: ensure compile and test targets run before packaging targets in the dependency chain.
- Avoid hidden local dependencies: keep third-party JAR handling explicit and documented.
- Plan gradual modernization: if migration is needed, map current Ant targets to Maven/Gradle equivalents before changing tooling.
If your organization still runs Ant for Java EE delivery, consistency matters more than novelty: clear target dependencies, centralized properties, and deterministic packaging will reduce build failures and deployment drift.
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.