Creating a Bundle Jar with Ant

I'm using Ant to build some Java projects.
In some, I've got a lib/ directory, which contains external dependencies, in the form on JAR files.

During the build, I create a bundled jar, that contains the project's code, alongside the dependencies, by adding to the bundle jar file a zipfileset for each of the jars in the lib/ directory.

The problem is, that every time I add a jar, or change names, I need to remember to update the build.xml file, as I couldn't find a way for adding those zipfilesets in an automatic manner that will include all jars in a certain pattern (e.g. lib/*.jar).

Is there a better way for doing this?

I've considered writing my own Ant Task for this, or using Groovy's ant API to do this programmatically, but was wondering if there's a way for doing this using "vanilla" ant.

4 Answers

In my target, I have something like this:

<jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
    <zipgroupfileset dir="dist" includes="*.jar"/>
    <zipgroupfileset dir="dist/lib" includes="*.jar" excludes=""/>

    <manifest>
        <attribute name="Main-Class" value="${main.class}"/>
        <attribute name="Class-Path" value="${mf.classpath}"/>
    </manifest>
</jar>

And here is how I build my classpath:

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

<pathconvert property="mf.classpath" pathsep=" ">
    <path refid="build.classpath"/>
    <mapper>
        <chainedmapper>
            <flattenmapper/>
            <globmapper from="*.jar" to="lib/*.jar"/>
        </chainedmapper>
    </mapper>
</pathconvert>

mf.classpath is used from the package target posted above. This part I copied from somewhere else, so I'm not all that familiar with it.

Quick edit. Javac needs to know about those jars too.

<path id="jars">
    <fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>

<target name="compile">
    <mkdir dir="${build.dir}"/>
    <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="jars" debug="on"/>
</target>
1

Use a zipgroupfileset. For example:

<target name="jar">
    <jar destfile="foo.jar" basedir="${dir.classes}">
        <zipgroupfileset dir="lib" includes="*.jar"/>
    </jar>
</target>

The zipgroupfileset is documented with the Zip task.

5

For those of you using NetBeans here is how you can create JAR archive with libraries bundled using zipgroupfileset:

<target name="-post-jar">

    <property name="store.jar.name" value="MyJarName"/>

    <property name="store.dir" value="dist"/>
    <property name="store.jar" value="${store.dir}/${store.jar.name}.jar"/>

    <echo message="Packaging ${application.title} into a single JAR at ${store.jar}"/>

    <jar destfile="${store.dir}/temp_final.jar" filesetmanifest="skip">
        <zipgroupfileset dir="dist" includes="*.jar"/>
        <zipgroupfileset dir="dist/lib" includes="*.jar"/>

        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>

    <zip destfile="${store.jar}">
        <zipfileset src="${store.dir}/temp_final.jar"
        excludes="META-INF/*.SF, META-INF/*.DSA, META-INF/*.RSA"/>
    </zip>

    <delete file="${store.dir}/temp_final.jar"/>
    <delete dir="${store.dir}/lib"/>
    <delete file="${store.dir}/README.TXT"/>
</target>

I've added this target definition to the end of build.xml file. Target name is -post-jar.

1

Here's an simple example of an ant target that will create a jar (named test.jar) that includes all jar files under the lib directory. Maybe this will solve your problem?

<target name="jar">
    <jar destfile="test.jar">
        <fileset dir="lib/" includes="**/*.jar" />
    </jar>
</target>
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest