Autojar - create jar archives automatically

By Bernd Eggink, Regionales Rechenzentrum der Universität Hamburg
e-mail: Bernd.Eggink@rrz.uni-hamburg.de
  1. Purpose
  2. History
  3. Usage
  4. Options
  5. File parameters
  6. Examples
  7. Compiling it yourself
  8. Bugs

1. Purpose

Autojar helps creating jar files of minimal size from different inputs like own classes, external archives etc. It starts from a given class (e.g., an applet), recursively searches the bytecode for references to other classes, extracts these classes from the input archives, and copies them to the output. The resulting archive will only contain the classes you really need. Thus you can keep the size and loading time of applets low or make applications independent of installed libraries.

In a similar way, autojar can search directories and archives for other resources (like image files), extract them and copy them to the output.

Note that the program can't tell which classes will be loaded dynamically (by Class.forName()). If you know these classes in advance, you can simply provide them on the command line. If you don't, however, autojar may be not suitable.

Autojar uses the excellent bcel package (http://jakarta.apache.org/bcel/). top

2. History

Version 1.2.1: Some bugs fixed.
New options: -e, -q, -D.
Wildcards ? and * allowed in search paths.
Improved dependency checking.
Missing files are reported.

Version 1.1: Along with option -p, a search path for non-class files may be supplied (e.g., .gif files). Alternatively option -b ("both") tells autojar to use the class path for non-class files, too. top

3. Usage

Program parameters may either be given on the command line or read from a text file.

autojar [option...] [file...]
autojar @file
In the second form, each line of the file is considered a program parameter.

top

4. Options

Option Meaning
-b Use classpath for non-class files.
-c classpath Class path in the usual format (system dependent), used to search for class files.

The name part of each component may contain wildcards * and ?. Example: If directory /foo contains the archives a.jar, b.jar, c.jar, the expression -c /ah/oh:/foo/*.jar expands to -c /ah/oh:/foo/a.jar:/foo/b.jar:/foo/c.jar. Unix users will have to quote the argument in order to avoid expansion by the shell.

The class path is initialized by the value of the environment variable $CLASSPATH (system property "java.class.path"), if set. The default is ".". Multiple instances are merged into one: -c /usr/foo -c /usr/bar is the same as -c /usr/foo:/usr/bar.

-D Debug mode, shows more detailed error output. Not normally used.
-e Search all jars in all Java extension directories (system property "java.ext.dirs"). Without this option, archives in $JAVA_HOME/jre/lib/ext that are to be searched must be specified explicitely.
-h Print help and exit.
-m manifest Path of the manifest file. The class in the Main-Class entry will be treated like classes given on the command line.
-o outfile Output file, mandatory.
-p searchpath Search path for non-class files, same format as class path.
-q Run silently. Don't issue warnings.
-v Verbose output.
-x prefix Exclude prefix. Directories and archives in the search path whose path names start with prefix are ignored. Multiple instances are allowed.
-- End of options. All remaining parameters are regarded non-options, even if starting with - .

top

5. File parameters

An arbitrary number of file or directory paths may be supplied. What happens depends on the file type:

Classes from the Java runtime library will never be included in the output.

At exit, if Option -q is not present, autojar prints a list of missing files. top

6. Examples

Example 1: An applet consists of a main class MyApplet plus several other classes, all in the directory classes. Additionally some classes from the archive /local/lib/foo.jar are used, and all image files in the directory images, which are referred to as "x.gif", "y.gif" etc. (that is, without the directory part). The jar file may then be created like this:

autojar -vc classes:/local/lib/foo.jar -o myapplet.jar MyApplet.class -C images '*.gif'
If you refer to your image file as "images/x.gif", "images/y.gif", replace -C images '*.gif' by 'images/*.gif'.

Example 2: An application consists of a main class Magic and 199 additional classes, mixed up with classes from other projects, sources, and all kinds of junk in your working directory (not a particularly good idea, of course). The file magic.mf contains the entry Main-Class: Magic. Now the call

autojar -o magic.jar -m magic.mf

creates the archive magic.jar, saving you from the need to supply all 200+ names individually.

Example 3: An application with main class com.wow.MyApp dynamically loads an driver by calling class.forName("org.blah.Driver"). You know that the driver uses classes from /usr/share/java/foo.jar.

autojar -o myapp.jar -c /usr/share/java/foo.jar classes/com/wow/MyApp.class org.blah.Driver.class
Classes used in Driver are searched for

Example 4: An Applet wants to load the images toolbarButtonGraphics/general/Cut16.gif and toolbarButtonGraphics/general/Paste16.gif from its own jar file:

    JButton cutButton = new JButton(new ImageIcon(getClass().getResource("toolbarButtonGraphics/general/Cut16.gif"))),
            pasteButton = new JButton(new ImageIcon(getClass().getResource("toolbarButtonGraphics/general/Paste16.gif"))),
    /* ... */
The images are contained in the archive /usr/local/jlfgr-1_0.jar, downloaded from Sun. To avoid extracting and re-inserting them manually, you could write:
    autojar -o myapplet.jar -p /usr/local/jlfgr-1_0.jar MyApplet.class \
        toolbarButtonGraphics/general/Cut16.gif toolbarButtonGraphics/general/Paste16.gif
If you need a lot of these images and don't care about file size, you could also write
    autojar -o myapplet.jar /usr/local/jlfgr-1_0.jar MyApplet.class 
This includes the whole content of jlfgr-1_0.jar in your archive. top

7. Compiling it yourself

If you want to compile autojar yourself, first get the bcel package. Make a classes directory, put bcel.jar in the classpath and compile Autojar.java:
javac -d classes -classpath classes:/usr/share/java/bcel.jar -sourcepath . de/uni_hamburg/eggink/autojar/Autojar.java
(replace /usr/share/java by the directory containing bcel.jar on your system). Now you can run autojar, but don't forget to include bcel.jar in the class path:
java -classpath classes:/usr/share/java/bcel.jar de.uni_hamburg.eggink.autojar.Autojar parameters...
If you prefer a self-contained archive you can create it by applying autojar to itself:
java -classpath classes:/usr/share/java/bcel.jar de.uni_hamburg.eggink.autojar.Autojar -vc /usr/share/java/bcel.jar:classes -o autojar.jar -m autojar.mf
top

8. Bugs

Most likely.

Please report bugs, wishes etc. to: Bernd.Eggink@rrz.uni-hamburg.de. top