|
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.
|