Java Servlet & JSP Cookbook

Problem

You want to create a JAR file with Ant.

Solution

Use the built-in jar task.

Discussion

The jar task automates the creation of JAR files. Like the war task for WARs, the jar task allows you to automate the command-line phrases you would have to type in for creating JARs. In this way, build files using the jar task are somewhat like shell scripts or batch files for creating JARs. The Sun Microsystems JAR file specification can be found at http://java.sun.com/j2se/1.4/docs/guide/jar/jar.html.

In web applications, JAR files are used to contain separate code libraries that the web application depends on, such as a database driver. They are located in a web application's WEB-INF/lib directory. Example 4-7 shows an Ant target that uses the jar task to create a JAR, and then copies the JAR file to the lib directory of a web application. These actions precede the archiving of the web application into a WAR file, which can be included in the same build file to automate everything at once (see Recipe 4.5 on creating WAR files).

Example 4-7. Creating a JAR file with Ant

<project name="jar-task" default="create-jar" basedir="."> <target name="init" description="Initializes some properties."> <echo message="Initializing properties."/> <property name="dist" value="dist" /> <property name="web" value="web" /> <property name="meta" value="meta" /> <property name="jar-name" value="myutils" /> </target> <target name="prepare" depends="init"> <echo message= "Cleaning up the build and dist directories."/> <delete dir="${dist}"/> <mkdir dir="${dist}"/> </target> <target name="create-jar" description="creates a JAR archive file" depends="prepare"> <jar destfile="${dist}/${jar-name}.jar" basedir="../../" includes="**/*.class **/${web}/*.html"> <fileset dir="../../images"/> </jar> </target> </project>

This build file contains three targets in the build sequence init prepare create-jar . These targets create some properties and clean up a directory called dist that contains the resultant JAR file. The create-jar target calls the jar task, which looks like:

<jar destfile="${dist}/${jar-name}.jar" basedir="../../" includes="**/*.class **/${web}/*.html"> <fileset dir="../../images"/> </jar>

The destfile attribute of the jar element specifies the location and name of the JAR file after it is created. I used a property called jar-name here, so that the user can run this Ant file from the command line and feed a new JAR filename into the build file if need be, as in:

ant -Djar-name=mynewjar.jar

Remember that any properties specified with the -D switch override the properties of the same name defined inside the build file.

The basedir attribute of the jar task identifies the top-level directory of files that will be included in the JAR. In the example, the pattern ../../ means "go up two directories from the basedir of this project"; in other words, go up two directories from where the Ant build file is located.

The includes attribute has two space-separated patterns (you can also separate them with a comma). The patterns further refine the types of files that will be included in the JAR file. The first pattern specifies the inclusion of all the files ending with the .class suffix that are located in zero or more directories beneath the basedir location. This JAR, as a result, contains all of the Java class files in all directories nested beneath the base directory; the JAR reproduces any nested directories that it finds with the class files. The other pattern ( **/${web}/*.html ) takes all directories nested beneath the base directory called web and includes any files that end with .html in the JAR. Once again, the nested directories will be included with the JAR and the HTML files.

Finally, a fileset element nested within the jar task grabs all the contents of the ../../images folder and includes them in the JAR, but it does not include the images folder itself . A way to include the images folder and its contents at the top level of the JAR is to change the jar task to:

<jar destfile="${dist}/${jar-name}.jar" basedir="../../" includes="**/*.class **/${web}/*.html **/images/*.gif "/>

This task adds a third pattern to the includes attribute ( **/images/*.gif ), which grabs all the GIF files contained by any images directories that are nested in the base directory (the value of the jar element's basedir attribute). An images directory will be included in the JAR if one is found.

The ** pattern is often used in Ant elements; it means "zero or more directories."

Manifest

The jar task creates a META-INF/MANIFEST.MF file for the JAR if the jar task's manifest attribute does not appear. The default manifest looks like this:

Manifest-Version: 1.0 Created-By: Apache Ant 1.5.1

If you want to specify the location of your own manifest file for reasons such as signing a JAR file or specifying the file that contains the main( ) method in an executable JAR, use the jar task's manifest attribute. This optional attribute can be either the file location of the manifest or the name of another JAR that has been added by using a nested fileset element. If it is a JAR, the task looks in that JAR for the META-INF/MANIFEST.MF manifest.

See Also

Recipe 4.1 on downloading and setting up Ant; Recipe 4.2 on writing Ant targets; Recipe 4.3 on creating a classpath for an Ant file; Recipe 4.4 on compiling a servlet with Ant; Recipe 4.7 and Recipe 4.8 on starting and stopping Tomcat with Ant; Recipe 2.1 and Recipe 2.6 on deploying web applications using Ant; the Ant manual section on the property task: http://ant.apache.org/manual/CoreTasks/property.html; the Ant manual segment on targets : http://ant.apache.org/manual/using.html#targets; the Apache Ant manual index page: http://ant.apache.org/manual/index.html; the Apache Ant Project: http://ant.apache.org.

Категории