The last Java wrapper script

One of my biggest Java pet peeves is the fact that a pristine, platform-independent Java application will frequently be shipped wrapped in a diseased blanket of shell scripting. Nominally, this wrapper script is there to set up the class path and invoke Java, acting as "glue" between the curmudgeonly operating system and this denarian virtual machine technology. The typical wrapper script is far from so reserved, unfortunately acting as a lint trap for all manner of minor enhancements presumably made in the name of programmer efficiency. In the long term, gratuitous use of multiple languages when one will do is the antithesis of efficiency (I am, of course, thinking of the poor guy who has to debug or maintain this stuff after the original author has skipped town).

As it turns out, a couple operating systems have support for direct execution of Java binaries. Coupled with an appropriately constructed JAR manifest (which can specify things often relegated to the wrapper script, e.g. the class path), this lets us eliminate these unsightly wrapper scripts in many cases.

Not all operating systems are so fortunate, though. I noticed this evening that trying to directly execute a chmodded JAR file under MacOS X gives me a disappointing "cannot execute binary file" error. To avoid introducing yet another garbage-collecting monstrosity to the world, and to avoid needing to create a new script for each new JAR I added to my growing army of Java commands, I decided to borrow a page from the isaexec playbook:

#!/bin/ksh -p
#
# runjava.sh: executes the JAR file whose name is used to run this script
#

BASE="$(basename $0)"
DIR="$(dirname $0)"
JARFILE="$DIR/jars/$BASE.jar"

[ -f "$JARFILE" ] && exec java -jar "$JARFILE" "$@"
echo runjava.sh: $BASE: command not found
exit 127

runjava.sh simply takes argv[0] as the name of a .jar file in the jars subdirectory of the directory argv[0] is in. Using it is as simple as creating a link to it. For example, I put mycmd.jar in ~/bin/jars, and linked ~/bin/mycmd to the script. Done.

Unfortunately, not all Java applications can be simplified in this manner. Class paths may vary from install to install (something like $ORIGIN here would be a dream come true), and LD_LIBRARY_PATH might be needed to find native libraries. I'm keeping my eye on JSR 277; hopefully it will provide the solution my fellow wrapper-script haters and I long for.

(Technorati) Tags:
Comments:

Wrappers are currently a necessary evil because things are often even worse than you suggest. Many Java applications (especially commercial ones) ship with their own JREs because they have really only been extensively tested with a single JRE. There are some tools to make cross platform launchers, but Java currently lacks a unified approach. This is one area where WebStart, applet, and ordinary applications should all be more unified.

http://launch4j.sourceforge.net/

Posted by Curt Cox on March 07, 2006 at 11:27 PM PST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

user12619391

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today