Packaging a Java App for Mac OSX

Posted by Aaron Walker on May 29, 2007 · 3 mins read
At JavaOne I noticed that a good 30-50% of developers had Macs and one thing that had always annoyed me about Java client applications on Mac OSX is that they just look and feel wrong and do behave like a Mac App. So after a bit of surfing around I found a couple of decent articles discussing different ways to improve this. One thing I love about Macs is the easy I can install, run and uninstall apps. Most Mac apps look like a single file (Application bundle) which is actually a special directory. So the information outlined below helps automate the process of creating an OSX app bundle which can easily be integrated into an existing ant build.

The ant target below is an example of how to package a Java application as a .app for OSX.
To use this target you need to have setup some ant properties such as:

${app.name} - the name of the application for example MyApp will result in MyApp.app in the ${dist.mac} directory
${dist.mac} - the directory where the resulting .app will be created
${javaappstub.dir} - is the path to the JavaApplicationStub for the Java version you want this app to run for example /System/Library/Frameworks/JavaVM.framework/Versions/Current/Resources/MacOS
${packaging.mac} - The location of mac specific artifacts such as Info.plist

<target name="osx.app" depends="jar">
<property name="appdir" value="${dist.mac}/${app.name}.app"/>
<mkdir dir="${appdir}"/>
<mkdir dir="${appdir}/Contents"/>
<mkdir dir="${appdir}/Contents/MacOS"/>
<mkdir dir="${appdir}/Contents/Resources"/>
<mkdir dir="${appdir}/Contents/Resources/Java"/>
<copy file="${javaappstub.dir}/JavaApplicationStub" todir="${appdir}/Contents/MacOS"/>
<copy file="${packaging.mac}/Info.plist" todir="${appdir}/Contents"/>
<copy file="${packaging.mac}/PkgInfo" todir="${appdir}/Contents"/>
<copy todir="${appdir}/Contents/Resources">
<fileset dir="${src}/images">
<include name="*"/>
</fileset>
</copy>
<copy file="${build}/${app-name}.jar" todir="${appdir}/Contents/Resources/Java"/>
<copy todir="${appdir}/Contents/Resources/Java">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
</copy>
<exec command="/Developer/Tools/SetFile -a B ${appdir}"/>
<exec command="chmod 755 ${appdir}/Contents/MacOS/JavaApplicationStub"/>
</target>

The Info.plist file is an XML configuration file that
completely defines an application. It tells OS X the name of the
application, how to start it, which icons to use, which files it
understands, and virtually every other config parameter you can imagine.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
...
<key>CFBundleIconFile</key>
<string>MyApp.icns</string>
<key>Java</key>
<dict>
<key>MainClass</key>
<string>com.base2.myapp.Main</string>
<key>JVMVersion</key>
<string>1.4+</string>
<key>ClassPath</key>
<array>
<string>$JAVAROOT/myapp.jar</string>
<!-- include any required jars as additional <string> elements -->
</array>
<key>Properties</key>
<dict>
<key>com.apple.mrj.application.apple.menu.about.name</key>
<string>MyApp</string>
<key>apple.laf.useScreenMenuBar>
<string>true</string>
<key>com.apple.macos.useScreenMenuBar</key>
<string>true</string>
</dict>
</dict>
</dict>

Also the PkgInfo file is a plain text file. If you have not registered a creator code with ADC, the contents should be APPL????. If you have registered a creator code replace the ???? with your creator code.

See apple's Java Dictionary Info.plist Keys for more details

See apple's documentation for additional configuration options

See apple's Java System properties documentation for more details about apple specific system properties