Skip to content

Executable Jars with One-Jar

I’ve been working on packaging a batch process so it can be run by some other group… nothing’s better than passing off the work onto someone else… (gotta love consulting!)

In doing so I’ve stumbled upon the problem of packaging and delivering a command-line app. This is where One-Jar project comes in. The promise of One-Jar is that you can package everything together and run it from anywhere. This is nice if, for example, you want to pawn off a batch process app to a support group that doesn’t know how to package and deploy stuff.

This post shows how I went about doing that, and the resulting ant target I created, as well as some of the pitfalls I experienced along the way.

The batch process app I put together is really just a single class that has a ton of dependent jar files, as well as some config files I want to override. When everything is set up the way it’s supposed by set up via One-Jar, the resulting exploded structure looks something like this:

/applicationContext.xml
/log4j.properties
/hib1.hbm.xml
/hib2.hbm.xml
/main/main.jar – my single class file packaged here * also contains a manifest that points to my main
/lib/ – a bunch of dependent jars
/com/* – the one-jar classes
/META-INF/MANIFEST – this manifest points to the one-jar classloader

To make a one-jar you need to do the following:

  1. Create your own main jar file with a manifest that points to your main method. In my case my manifest looks like this (notice I’m not worrying about the classpath):

    Manifest-Version: 1.0
    Ant-Version: Apache Ant 1.6.5
    Created-By: 1.4.2_04-b05 (Sun Microsystems Inc.)
    Main-Class: com.batch.stuff.MyMainClass
  2. Create your executable jar that contains a lib directory with your dependent jars, and your main directory and main jar as above. Also include your property and config files at the base like they normally would be. *My friend Steve pointed out that it’s probably best to test the jar at this point. If you’ve created the jar you should be able to run the jar from the same directory…
  3. And make sure you don’t accidentally add the one-jar jar into the jar you’re packaging. :-)
  4. Update your executable with the exploded contents of the one-jar jar. This is easily performed via the command-line, like so:

    $ mkdir boot
    $ cd boot
    $ jar -xvf ../one-jar-boot.jar
    $ jar -uvfm ../myapp.jar boot-manifest.mf .

After working with this for a while, I was able to create an ant task that can do it.
Here’s the ant task I created to jar up my batch process:


depends="init, compile.myapp"
description="Jars the contents of the classes
directory into a myapp specific jar">









basedir="${myapp.basedir}/classes"
update="true"
manifest="${myapp.basedir}/classes/myapp-manifest.mf"/>


update="true">











dest="${myapp.basedir}/boot" />


update="true"
duplicate="preserve"
manifest="${myapp.basedir}/boot/boot-manifest.mf"
basedir="${myapp.basedir}/boot"
/>


This creates an executable jar file that can be executed like this from any directory on any system:


java -jar MyApp.jar

Alternatively, to see the classloader info:


java -Done-jar.info -jar MyApp.jar

Other Resources

This is a good article
written by the author of One-Jar.

Supposedly you can use an eclipse plugin too

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*