Tuesday 7 August 2012

Java Packaging

jar (http://ant.apache.org/manual/Tasks/jar.html)

The basic mechanism for packaging Java code is within a jar file. This can be achieved in ant using the jar task. The jar task is more powerful than it first appears as you can use a nested zipfileset to package multiple source jars into a single output jar.

However, the danger with this mechanism is that you may end up packaging a version of a class which conflicts with the version required by another dependency.

jarjar (http://code.google.com/p/jarjar/)

jarjar extends the default jar ant task with a new "rule" child element which specifies mappings of package names. This rewrites all the classes within the output jar to move the classes within the specified packages and update all the references to these classes.

For example org.apache.commons.io could be moved to com.product.internal.commons.io. This is one way to avoid the classic jar hell.

jarinjarloader (no site)

The jarinjar classloader is an internal part of the Eclipse JDT project. However, you can get the classes by opening org.eclipse.jdt.ui_*version_number*.jar with an archiver and extracting the file jar-in-jar-loader.zip.

With the aid of these classes it is possible to package a jar within another jar and still load the contained classes and resources. For an example of what this looks like in practice you can look at getSWTClassloader() in SWTLoader.java.

Another project which claims to do the same is One-Jar (http://one-jar.sourceforge.net/). However, I haven't used this myself.

swtjar (http://mchr3k.github.com/swtjar/)

The standard approach to packaging SWT applications is to create a bundle per platform (32/64 bit and Win/Linux/OSX). This is because SWT requires the application to load the correct jar for the platform being used.

However, with the help of the jarinjar loader classes it is possible to include multiple SWT jars within an application jar and then use standard platform detection code to pick the correct one to programmatically add to the class path. My swtjar project packages this solution as an ant task.

jarbundler (http://informagen.com/JarBundler/)

OSX has its own package format to allow an application to provide an icon and control startup options. This is particularly useful as SWT on OSX requires an extra command line argument to work. The jarbundler project is an ant task that helps you to build OSX application bundles.

For details about using this tool you should refer to this page: http://mchr3k.github.com/swtjar/osxapp.html