Beginners Guide to Ant for Java Applications
From Coder's Log
Every Java project needs some sort of a basic build environment. This guide will cover the basic usage to compile, create jars, and to execute your code.
Lets start with the basics
Assuming you are working on a single project, where the libraries(external .jars) are located within the project in the lib folder, your java source is located in src folder such that your folder structure looks like src/com/company/package, and not src/java/com/company/package.
<project name="MyProject" basedir="."> <path id="classpath.base"> <fileset dir="lib" id="fileset.libs.base"> <include name="**/*.jar" /> </fileset> </path> . . . </project>
Every project must have a name, the basedir typically points to the root of the project which is where the eclipse will execute the build from, and where the build.xml will be located
We create a base classpath to use in other targets as our project grows we will be able to modify this path. The same class path will also be used to create the dist folder.
<fileset> tag in ant represents a basic unit of file selection, it can have multiple include or an exclude sub elements which define ant based patterns. Note the "fileset.libs.base" it will be used later in the dist tag to reference the fileset that created the classpath.
Ant uses the following common patterns
- *.jar - select all files with the extension jar in the folder specified by dir attribute
- **/*.jar - select all files with the extension jar in the folder specified by dir attribute and all of its sub folders.
- ** - select all files in all subfolders
Now that we have our classpath defined, lets look at which targets we are going to need. A target in Ant is a unit of work to be done
<target name="compile" description="compile files" depends="clean, create-dirs">
every target must have a name, if the description is not specified eclipse will consider the target internal and optionally hide it for convenience.
a target can depend on any number of other targets.
Lets look at some basic targets to clean and create our build/dist folders
<target name="clean"> <delete dir="build" /> <delete dir="dist" /> </target> <target name="create-dirs"> <mkdir dir="build" /> <mkdir dir="dist" /> </target>
The clean target will delete the folders and their contents, and the create-dirs target will create empty folders.
Now that we have our folders lets compile our java files.
<target name="compile" depends="clean, create-dirs"> <javac debug="true" srcdir="src" destdir="build"> <classpath refid="classpath.base" /> </javac> <copy todir="build"> <fileset dir="src"> <include name="resources/**"/> </fileset> </copy> </target>
The javac task is pretty straight forward, we define our srcdir, and our destdir. javac task can also define an optional exclude clause which is defined much like the one in the fileset.
Typically we also need to copy some resources from our src folder to the build one, since javac will only take care of the .java files. NOTE: eventhough all resources are located in the src/resources folder the fileset defines "src" as its directory, and the resources is used in the include. If fileset where to use src/resources as its directory, then the resources would be copied directly into the build, not into build/resources.
We are finally read to create our dist target that will package everything together
<target name="dist" description="Create Jar" depends="compile"> <jar destfile="dist/myproject.jar"> <fileset dir="build" /> </jar> </target> <copy todir="dist"> <fileset refid="fileset.libs.base"/> </copy>
The jar task create a jar file based on a set of filesets and the copy task copies all libraries used as part of the classpath to the dist folder as well for easy packaging. If this where a web application, you can use the war task to create a war file. That will be addressed in a separate article.
