Saturday, December 29, 2012

Netbeans-Like Distribution with Maven

When it comes to creating standalone Java applications, out of the box maven projects are not easy to distribute, they don't have configured some default main class (or some convention), dependencies are not specified on the manifest and also dependency jars are not packaged even near the final jar file.

On the other hand, if you have used Netbeans IDE to create standalone Java apps, you can notice that upon any build, the default Netbeans ant build script places a "dist" folder inside your project with the following structure:

This folder is the distribution of your app and you may simply run it with the java -jar command line.

Even though Maven projects have a lot of advantages, I personally miss how handy it is this structure for distribution; so I managed to make this happen with maven and it's assembly plugin.

Building the Distribution Structure

In order to create the desired distribution, I started with maven's jar-with-dependencies predefined assembly and customized it to look like the following:

What this does is the following:

  • It compresses the whole distribution into a nice zip file inside the target directory.
  • The first dependency set is there to copy the application jar on the root of the distribution, I added the none scope to make sure that no other dependencies are copied there.
  • The second dependency set is to copy all dependencies and transitive dependencies into the lib folder.
Now this takes care of the packaging but there is still some work to do, so we need to edit our project's pom.xml file and add the following configurations:

First of all, I've changed the final name of the archive to be short and sweet. Next, I've configured the assembly plugin to point to the right configuration file. Finally I've configured the jar plugin to set in the MANIFEST.MF file the main class and the jars that should be included on the classpath. Please note that you should alter the mainClass configuration to match you main class.

After this, we can create our distribution by simply running:
$ mvn clean package assembly:single

You should find a zip file called like your artifact's ID-dist.zip, which you can nicely share and it's easily run.