Build the classpath string for an executable Jar with ant

These days i need to deliver a Java program and faced the problem to generate the classpath string for the manifest file. After struggling around i managed to let ant build this string. I wonder why there isn’t an attribute in the manifest task which can deal with an classpath fileset.

OK, here is my solution (i post it mostly for me – to keep it in memory.. ) which uses a filesetpath and the
pathconvert task.

The directory structure should look like this:

dist
|- lib
| |- x.jar
| |- y.jar
| |- z.jar
|- executable.jar
|- start.bat

Where all needed librarys (eg. log4j.jar, spring.jar etc.) are stored in a subdirectory called lib.

In the ant build.xml we define some properties and the classpath:

         
         <property name="src.dir" value="src" />
         <property name="src.lib.dir" value="librarys" />

        <property name="dist.dir" value="dist" />
	<property name="dist.dir.location" location="dist" />
        <property name="dist.lib.dir" value="lib" />

        <path id="compile.classpath">
		<fileset file="${src.lib.dir}/x.jar" />
		<fileset file="${src.lib.dir}/y.jar" />
		<fileset file="${src.lib.dir}/z.jar" />
       </path>

The interesting thing is the dist.dir.location which is defined as location. This enables us to use the given relative path as absolute path in the pathconvert task.

Before we build the manifest we need to copy the librarys to the lib folder and build the classpath string out of the classpath fileset. This String will passed to the manifest task an specify the classpath relative to our executable jar.

        <!-- copy all needed librarys into the lib folder -->
	<copy todir="${dist.dir}/${lib.dir}" flatten="true" verbose="true">
		<path refid="compile.classpath" />
	</copy>

Now we create a new path out of al librarys stored in the lib folder. This path wil be used to build the classpath string for the manifest file. This is necessary to create consistent path information in the
lib.classpath path (maybe some of your librarys in the project a stored in different places). Now they all have a path like c:/project/dist/lib/x.jar; c:/project/dist/lib/y.jar …

	
	<path id="lib.classpath">
		<fileset dir="${dist.dir}/${lib.dir}">
			<include name="*.*" />
		</fileset>
	</path>
       

After this we convert the path information into a string which is java classpath conform:
./lib/x.jar ./lib/y.jar ….

      <!-- convert lib folder to string property for use in manifest classpath-->
	<pathconvert property="string.classpath" pathsep=" ">
		<path refid="lib.classpath" />
		<map from="${dist.dir.location}\" to=".\" />
	</pathconvert>

Now we can use ${string.classpath} to build the manifest:

       <!-- create the manifest file -->
	<manifest file="${src.dir}/MANIFEST.MF">
		<attribute name="Implementation-Title" value="MyProject" />
		<attribute name="Implementation-Version" value="0.0.1" />
		<attribute name="Implementation-Vendor" value="Me" />
		<attribute name="Main-Class" value="de.koelnerwasser.SuperApp" />
		<attribute name="Class-Path" value="${string.classpath}" />
	</manifest>

And jar the mainproject:

        <!-- jar all the stuff -->
	<jar jarfile="${dist.dir}/MyProject.jar" basedir="${src.dir}" 
         manifest="${src.dir}/MANIFEST.MF" />

To start the Application in windows, it’s useful to put a start.bat file in the dist folder. The bat is easy – it only starts the jar..

java -jar MyProject.jar
pause

1 thought on “Build the classpath string for an executable Jar with ant

  1. Thanks dude, long time since I’ve had to do this and this was exactly what I needed.

Leave a Reply

Your email address will not be published. Required fields are marked *