RSS feed
<< September 18, 2007 | Home | September 20, 2007 >>

Packaging Java apps for OS X with Maven

Anyone attending a Java conference the past few years must have noticed the steady increase of Java developers working on a Mac. The good looking hardware sure helps, but the main reason people are flocking to the Mac is OS X.

Apple's operating system is a great platform for Java developers since it combines the power of Unix with a UI that is actually possible to use. Installing an application is as easy as downloading it and dragging it to the Applications folder.

But that's until you try to install Java software. Some projects are helpful and create double-clickable jars, others just reuse the scripts from their Linux distribution and force you to start Terminal just to lauch their app.

The reason for this is probably that hand-crafting Java application bundles for OS X is quite tedious. A while back I decided to do something about this sad state and make the Java world a better place to be for Mac people.

What I did was to create a Maven plugin that will take any Maven project  and make it into a first class OS X application bundle.

But first, a little motivational example to illustrate why you should care about this:

My friend Sigurd has made this cool little Java app called "Hva" that helps you keep track of hours. Every now and then it will pop up and ask you what you've done  since last time.



(For those of you who's Norwegian is a little rusty: "Hva" translates to "What" and this dialog asks what you've been up to since 7:36 PM)

Because Sigurd is one of these helpful guys, he distributes his app as a double-clickable jar file.

Like any other application, I dragged the jar file to the Applications folder on my Mac and this is what it looks like:



This really isn't too bad, but there are some subtle things that tells me this is not a properly bundled OS X application. First "Hva?" is the only application that has a file name suffix (".jar") in it's name.  Second, the logo of the application is the generic and dull Java Application logo.

So what can Sigurd do to give the users of Hva a better experience on the Mac?

Well, if he's using Maven (and he should!) there is no longer any excuse for giving his Mac users a bellow par experience of his application:

Yesterday I released the OS X Application Bundle Maven plugin which is a part of the Mojo project over at Codehaus.

All you need to give this plugin is  a main method to launch and it creates a beautiful OS X application bundle ready for clicking by your users.

In order to use this plugin for Hva, Sigurd could add hva.jar to his Maven repository and create a Maven project with this pom.xml:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>hva</groupId>
<artifactId>hva-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<name>hva</name>
<dependencies>
<dependency>
<groupId>hva</groupId>
<artifactId>hva</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>

Then he needs to add the following plugin configuration:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>osxappbundle-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<configuration>
<mainClass>Hva</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
</plugin>

Running mvn:install should now create an OS X application bundle in the project's  target directory:


As you can see, the plugin has created an application bundle, plus packaged the application in both a zip and a disk image file ready for distribution.

This is nice, but what if Sigurd wants to add a custom icon to Hva? First he needs to open the Icon Composer utility located in /Developer/Application/Utilities/Icon Composer:


 

Here, I've created an icon in various sizes from the photo in my collection that looked most like the letter "H". I've stored this file as "hva.icns" in src/main/app-resources and used the iconFile property to tell the plugin where it can find the icon, like this:

<plugin>
<groupid>org.codehaus.mojo</groupid>
<artifactid>osxappbundle-maven-plugin</artifactid>
<version>1.0-alpha-1</version>
<configuration>
<mainclass>Hva</mainclass>
<iconFile>${basedir}/src/main/app-resources/hva.icns</iconFile>
</configuration>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
</plugin>

After running mvn:install, our target/ directory now looks like this:



Let's rename it and move it to the Applications folder:


Notice the neat icon on the application and how much smoother it looks in the Dock now:


 

See the plugin's site for full documentation. The Maven example project I created for Hva can be found in the Simplericty Subversion repository, here:

http://simplericity.org/svn/simplericity/projects/hva-maven/