Deliver Your Java Application in One-JAR™!

Copyright 2004-2010 by P. Simon Tuffs, All Rights Reserved. http://www.simontuffs.com




Background

The Java Runtime Environment supports running a Jar file using the following syntax:

java -jar jarname.jar
The only requirement of the jarname.jar file is that it contains a manifest attribute with the key Main-Class a main class to run, for instance in the META-INF/MANIFEST.MF file:
Main-Class: com.mydomain.mypackage.Main
Any non-trivial Java application is going to rely on any number of supporting Jar files. For example, using the Apache Commons Logging capabilty to do logging an application will need to have the commons-logging.jar file on its classpath. Most developers reasonably assume that putting a dependency Jar file into their own Jar file, and adding a Class-Path attribute to the META-INF/MANIFEST will do the trick:

jarname.jar
| /META-INF
| |  MANIFEST.MF
| |    Main-Class: com.mydomain.mypackage.Main
| |    Class-Path: commons-logging.jar
| /com/mydomain/mypackage
| |  Main.class
| commons-logging.jar
Unfortunately this is does not work. The Java Launcher$AppClassLoader does not know how to load classes from a Jar inside a Jar with this kind of Class-Path. Trying to use jar:file:jarname.jar!/commons-logging.jar also leads down a dead-end. This approach will only work if you install (i.e. scatter) the supporting Jar files into the directory where the jarname.jar file is installed.

Another approach is to unpack all dependent Jar files and repack them inside the jarname.jar file. This approach tends to be fragile and slow, and can suffer from duplicate resource issues.


If you like One-JAR then you might want to check out some of the other Open-Source projects developed by simontuffs.com:
Get One-JAR(TM) at SourceForge.net. Fast, secure and Free Open Source software downloads soap-stone at sourceforge.net Eclipse JAR Plugin Yet Another Compiler Compiler Language