One of the most useful things you can do for any project is provide command line friendly tools for administration, diagnostics and maintenance. As nice as browser based administration tools are, not everyone has access to production machines behind firewalls and the sort with a browser, most administration is done via ssh. Giving operations tools that they can interconnect with normal Unix development tools makes their life and your life a whole lot better. They can build the tools they need with the foundation tools you provide.

In the past I have written most of my command line programs in Python. It is batteries included, standard on any Unix or Linux distribution worth using, and it just works. I have recently been introduced to Groovy and have been using it to produce some very sophisticated tools in a very short period of time.

But one of the downsides is that it inherits all the deployment difficulties of Java as well as all the benefits like the extensive standard library and third party code available. Even as easy as it is to add Groovy to the Extensions directory of your JDK installation, it doesn’t help your end users who might not know how to do such a thing. Everyone loves a standalone executable. Having to add a bunch of .jar files to your CLASSPATH environment variable isn’t any better or portable. Wrapper shell scripts aren’t a perfect solution either, bash is pretty ubiquitous, but not everyone uses bash, and what about Windows?

The best solution is to bundle your application with all its dependencies in a single .jar file. For most things this is a great way to distribute command line tools to hosting operations personnel and other end users that might not be Java experts. But this isn’t the easiest thing to accomplish with the basic jar tool that sun provides. Here I present a simple Ant based solution that can be modified and used to bundle any code base up into a standalone executable .jar file that can be executed on any platform that support Java, without any of the dependencies needing to be installed before hand.

Here is a basic build-jar target.

What this will do is it wil include all the contents of the .jar files listed in dependencies.list file that is in your ${lib.dir} in with your .class files from your ${build.dir}/classes directory and set the default executable class to main. The dependencies.list is just a plain text file with the name of each .jar file to include on each on a separate line. Here is an example.


Update: I use Maven 3 and the Shade plugin exclusively now to do this, really put Ant down and learn Maven 3.x you will thank me!