Summary: This tutorial shows how to use a list of jar files in a lib directory to create a dynamic classpath you can write to a manifest file using an Ant build script.
In this tutorial I'd like to demonstrate how to convert a list of jar files in a standard lib directory into a classpath string you can use to define a manifest file in an Ant build script. By converting this list of jar files into a classpath string, the build process for your jar file can depend on any number of external jar files, and you can create this classpath dynamically.
Jar files in my lib directory
In my case, the Java application I was building depended on the following jar files, which were in the lib directory of my project:
commons-collections.jar commons-dbcp-1.1.jar commons-pool-1.1.jar log4j-1.2.8.jar
Ant tasks to build the dynamic classpath
My ant script contains several sections that deal with this classpath issue. The first thing I do is create a classpath variable named build.classpath
that contains a list of all the *.jar
files in my lib
directory, like this:
<path id="build.classpath"> <fileset dir="lib"> <include name="**/*.jar" /> </fileset> </path>
Next, I convert that build.classpath
list into a space-separated string (named mf.classpath
) using an Ant task named pathconvert, and a mapper named flattenmapper. This is shown in the next section of my Ant build script:
<!-- convert classpath to a flat list/string for use in manifest task --> <pathconvert property="mf.classpath" pathsep=" "> <path refid="build.class.path" /> <flattenmapper /> </pathconvert>
The net effect of these two sections of code is turning this list of jar files in my lib
directory
commons-collections.jar commons-dbcp-1.1.jar commons-pool-1.1.jar log4j-1.2.8.jar
into a space-separated string like this
commons-collections.jar commons-dbcp-1.1.jar commons-pool-1.1.jar log4j-1.2.8.jar
Building the manifest and the jar
In the final two steps of the process I first build a manifest file (MANIFEST.MF
), using the mf.classpath
variable, like this:
<tstamp/><!-- needed for TODAY --> <manifest file="MANIFEST.MF"> <attribute name="Built-By" value="${manifest.built.by}"/> <attribute name="Created-By" value="${manifest.created.by}"/> <attribute name="Main-Class" value="${manifest.main.class}"/> <attribute name="Implementation-Version" value="${version.number}-b${build.number}"/> <attribute name="Built-Date" value="${TODAY}"/> <attribute name="Class-Path" value="${mf.classpath}" /> </manifest>
And then I use that manifest file to build my jar file, like this:
<!-- create the jar file, including the manifest file we just created --> <jar basedir="${dest.dir.classes}" destfile="${package.file}" includes="**/*.*" excludes="**/*Test*" manifest="MANIFEST.MF" />
Hopefully all of this makes sense. It's fairly complicated, but I've tried to break it down here to just the essential steps of the build process.