Creating a bundle jar with ant

JavaAntJar

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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 - Java

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.

Solution 3 - Java

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.

Solution 4 - Java

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionabyxView Question on Stackoverflow
Solution 1 - JavajonescbView Answer on Stackoverflow
Solution 2 - JavaJason DayView Answer on Stackoverflow
Solution 3 - Javauser725434View Answer on Stackoverflow
Solution 4 - JavaUpgradingdaveView Answer on Stackoverflow