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.


Solution 1:

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>

Solution 2:

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.