2

I have a bunch of java command-line programs I've written and would like to install for all users.

Building with NetBeans, I get a /dist directory which contains myprog1.jar and a /libs directory with all the necessary libraries. The usual method to run is to go there and java -jar my.jar -options.

So what I'd like to do is just type myprog1 -options from anywhere and have it run.

The method I have thought of is:

  1. Create /opt/myjava/myprog1 which contains myprog1.jar and its /libs.
  2. Create a bash script myprog1 in /usr/local/bin which simply redirects all of the command line args to java -jar /opt/myjava/myprog1/myprog1.jar

I'm not too keen on bash scripting... if this is a reasonable method, what would that script look like, given that each program has a variable number and order of arguments? Does the script have to also worry about standard Unix bits such as output redirect > and pipes |?

3

Bash and the Java executable know how to handle the redirection stuff. You want to use exec in order to replace the script interpreter running the shell script.

#!/bin/bash
exec java -jar ....jar "$@"
1

You can write a single wrapper script that executes a jar named after the way it's called, and make one symbolic link for each jar. Here's the jar-wrapper script (warning, typed directly into the browser):

#!/bin/sh
name=$(basename "$0")
jar=
for dir in /opt/myjava/*; do
  if [ -e "$dir/$name.jar" ]; then jar=$dir/$name.jar; break; fi
done
if [ -z "$jar" ]; then
  echo 1>&2 "$name.jar not found"
  exit 126
fi
exec /your/favorite/java -jar "$jar" "$@"

Then create as many symbolic links to the wrapper script as you like, and put them in your $PATH if you want:

ln -s wrapper-script myprog1
ln -s wrapper-script myprog2

If you are running Linux, and you are the system administrator, then you can select a Java interpreter to make jars directly executable, thanks to the binfmt_misc mechanism.

For example, on my system:

$ cat /proc/sys/fs/binfmt_misc/jar
enabled
interpreter /usr/lib/jvm/java-6-sun-1.6.0.07/jre/lib/jexec
flags: 
offset 0
magic 504b0304

This system is documented in Documentation/binfmt_misc.txt in the Linux kernel documentation. To create an entry like the one above, run the command

jexec=/usr/lib/jvm/java-6-sun-1.6.0.07/jre/lib/jexec
echo >/proc/sys/fs/binfmt_misc/register ":jar:M:0:504b0304::$jexec:"

Your distribution may have a mechanism in place for binfmt registration at boot time. On Debian and derivatives, this is update-binfmts, and the JVM packages already register jexec.

If you need to pass options, register a wrapper script that adds the options instead of jexec directly.

1
  • Thanks for the script, it worked unmodified. I put the symbolic links in /etc/rc.local, creating links in /usr/local/bin.
    – Pete
    Sep 29 '11 at 4:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.