Appjar, jars-in-a-jar
Appjar is another approach to delivering jars-in-a-jar, like onejar. The difference is that most existing solution use classloaders to read the jars-in-a-jar. But certain scenario's won't play nice with this approach, for example when trying to use runtime weaving like "-javaagent:eclipselink.jar". This results in a chicken-and-egg problem; you need the jar to start java, but java needs to be started to unpack the jar.
Appjar works by creating a temporarily directory and unpacking all contents (except Appjar.class itself) to that directory. Then startup scripts are generated; simple straight forward shell or CMD scripts and these scripts are then executed using Runtime.exec. Per default Appjar then binds to the stderr and a stdout of the spawned process, so its output is reflected in the console. And per default Appjar then waits for the process to terminate; when this happens attempts are made to delete the temporarily directory.
An Appjar-jar is a jar containing all other jars and libraries, plus Appjar.class and a manifest controlling Appjar. For example:
my.jar
|- common1.0.jar
|- jtrayicon.dll
|- application.jar
|- Appjar.class
|- META-INF
|- MANIFEST.MF
The manifest controls the Appjar:
Main-Class: Appjar appjar-startup: application.jar
When "java -jar my.jar" is executed, the JAR is unpacked and application.jar is started.
Appjar can be used in two ways:
- start a jar
- start a class
1) When starting another jar, the creator of the appjar is responsible for the MANIFEST.MF inside the to-be-started jar. This means making sure that the classpath entries match the libraries that are available.
2) The other approach is starting a class. In this approach Appjar will automatically build a CLASSPATH containing all unpacked jars and libraries in the root directory of the appjar-jar. In this way there is no manual classpath maintenance.
An example ANT target to build an appjar:
<jar destfile="my.app.jar">
<fileset dir="path/to/appjar" includes="Appjar.class"/>
<fileset dir="build" includes="main.jar"/>
<fileset dir="lib">
<filename name="*.jar"/>
</fileset>
<fileset dir="dll">
<filename name="*.dll"/>
</fileset>
<manifest>
<attribute name="Main-Class" value="Appjar"/>
<attribute name="appjar-startup" value="org.myapp.Main"/>
</manifest>
</jar>
For more detailled information read the javadoc information available in the Appjar.java source file.





