tags:

views:

847

answers:

3

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.

Thanks!

A: 

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>
Dave Paroulek
Can jar files simply be nested? Are you sure this will work?
abyx
hmmm, I guess not, I was thinking wars and webapps instead of jars, sorry 'bout that.
Dave Paroulek
+2  A: 

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>
jonescb
Seems like what I was looking for! thanks
abyx
+2  A: 

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.

Jason Day
As jonescb answered, that really is the solution. Never saw it, as it's hidden in the Zip task
abyx