2008-05-29

Another step towards human-faced Java: single binary

I've found a nice way to produce classical 'single binary' applications developed in Java without sacrificing their portability.
Java apps are typically packaged as JAR files.  Format-wise, a JAR is actually a ZIP.  ZIP file format is end-anchored; a ZIP file remains processible if random bytes are prepended to it.
Therefore, if we package a Java application as a standard standalone JAR file, make sure the Main-Class manifest attribute is properly set up, and prepend these two lines to the file:
#! /bin/sh
exec java -jar "$0" "$@"
we get a file that is, at the same file, a JAR containing all the original content, and a shell script that, when executed, invokes JVM instructing it to then interpret the JAR as a standard Java app.  It also passes on all the original arguments and the exit code of the JVM, as expected.
The result behaves pretty much like a standard binary.  The primary restrictions are that JRE needs to be installed in a PATH-findable way, and suid doesn't work on such pseudo-binaries on most systems.  The primary advantage is that such a binary does not depend on the host architecture or even the OS (as long as it is a Unix, that is).  An interesting secondary advantage is the standard resource handling mechanism inherent in the concept of using JARs for applications.

No comments: