Deliver Your Java Application in One-JAR™! Copyright 2004-2007 by P. Simon Tuffs, All Rights Reserved.

Introduction

Java developers often come to a point where they wish to deliver their application as a single Jar file. 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. Suppose the application entry point is the class com.mydomain.mypackage.Main. Add the following line to the META-INF/MANIFEST.MF file:
Main-Class: com.mydomain.mypackage.Main
So far so good. But, here's where the problems usually start. 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 such a 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 not the case. The Java classloader does not know how to load classes from a Jar inside a Jar. The entries on the Class-Path must be references to files outside the Jar file, defeating the goal of delivering an application in a single Jar file.