Little Santi
Little Santi

Reputation: 8833

How to build a WAR with ANT including an arbitrary, custom classpath

I have to build a WAR file from an ANT script. I have declared a fileset with the compile classpath made of arbitrary libraries (in the following example they are only 2. In my real case, up to 90). I would like to include the same set of libraries in the war withouth having to declare all of them in both places: within the <javac> and within the <war> task.

This is my ANT script:

<project name="war-with-custom-classpath" basedir=".">

    <property environment="env" />
    <property name="lib" location="${env.USERPROFILE}/.m2/repository" />
    <fileset id="my.classpath" dir="${lib}">
        <include name="commons-pool/commons-pool/1.5.6/commons-pool-1.5.6.jar" />
        <include name="commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" />
    </fileset>

    <target name="compile">
        <javac srcdir="src/test/java" classpathref="my.classpath">
        </javac>
    </target>

    <target name="war">
        <delete file="mywar.war" />
        <war destfile="mywar.war" needxmlfile="false">
            <lib refid="my.classpath">
            </lib>
        </war>
        <!--Read the created war to see its contents-->
        <exec command="jar ft mywar.war">
        </exec>
    </target>

</project>

... but altough the libraries are included into the final war, they preserve their original paths like this:

META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/lib/
WEB-INF/lib/commons-logging/
WEB-INF/lib/commons-logging/commons-logging/
WEB-INF/lib/commons-logging/commons-logging/1.1.1/
WEB-INF/lib/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
WEB-INF/lib/commons-pool/
WEB-INF/lib/commons-pool/commons-pool/
WEB-INF/lib/commons-pool/commons-pool/1.5.6/
WEB-INF/lib/commons-pool/commons-pool/1.5.6/commons-pool-1.5.6.jar

Is there any form of including the JARs after stripping them from its paths? Like this:

META-INF/
META-INF/MANIFEST.MF
WEB-INF/
WEB-INF/lib/
WEB-INF/lib/commons-logging-1.1.1.jar
WEB-INF/lib/commons-pool-1.5.6.jar

I've already tried:

<lib refid="my.classpath" prefix="/WEB-INF/lib"/>

... but the result is still the same.

I've also tried:

<lib refid="my.classpath" fullpath="WEB-INF/lib"/>

or

<lib refid="my.classpath" fullpath="/WEB-INF/lib"/>

... and it turns on error Cannot set both fullpath and prefix attributes.

And I've also tried:

<zipfileset refid="my.classpath" fullpath="WEB-INF/lib" />

... but it turns on error fullpath attribute may only be specified for filesets that specify a single file.

And I've also researched in the Ant Manual and in SO, but no fortune so far.

Upvotes: 3

Views: 242

Answers (1)

Chad Nouis
Chad Nouis

Reputation: 7051

Consider using a <mappedresources> containing a <chainedmapper> that. The chain mapper, in turn, contains a <flattenmapper> followed by a <globmapper>...

<war destfile="mywar.war" needxmlfile="false">
    <mappedresources>
        <fileset refid="my.classpath" />
        <chainedmapper>
            <flattenmapper/>
            <globmapper from="*.jar" to="WEB-INF/lib/*.jar" />
        </chainedmapper>
    </mappedresources>
</war>

<mappedresources> replaces <lib> in the <war> task.

The <flattenmapper> strips the directories from the file paths in the <fileset>. The <globmapper> adds the directories back.

<mappedresources> requires at least Ant 1.8.

Upvotes: 2

Related Questions