Thursday, February 23, 2012

Swing applications deployment on Mac OS X

The most convenient way to deploy Java application on Mac OS X is to package it as application bundle. Bundle is nothing more then a directory with specific file structure beneath it. On Mac OS X, bundles are treated specially, while on other OS-es they appear simply as a directory with .app suffix.

The first step is to create correct directory structure. It is shown in the following image:
Application bundle directory structure


As mentioned above, bundle is nothing more then a directory with specific structure and some configuration file. On the above image, you can notice that subdirectory Contents contains the following files and directories:
  • MacOS - this directory contains application as it should be laid out on hard disk
  • Resources - any application specific resources should go here, such as localizations, images, sounds etc. For this sample, this directory is empty.
  • Info.plist - XML configuration file which contains bundle information
Untill this point, everything seems pretty straight forward, except Info.plist file. This is simple XML file, with specific structure. Contents of this file are shown in the following listing:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>CFBundleDisplayName</key>
 <string>My sample application</string>
 <key>CFBundleExecutable</key>
 <string>launcher.sh</string>
 <key>CFBundleIdentifier</key>
 <string>com.domain.myapp</string>
 <key>CFBundleName</key>
 <string>myApp</string>
 <key>CFBundlePackageType</key>
 <string>APPL</string>
 <key>CFBundleSignature</key>
 <string>myap</string>
 <key>CFBundleVersion</key>
 <string>1.0.0</string>
</dict>
</plist>

The meaning of each key is the described bellow:
  • CFBundleDisplayName - bundle name as displayed in Finder
  • CFBundleExecutable - executable code for bundle. In this case, it is a script to run tha application
  • CFBundleIdentifies - unique bundle ID
  • CFBundleName - short display name of the bundle
  • CFBundlePackageType - should be APPL for application
  • CFBundleSignature - four letter code of bundle creator
  • CFBundleVersion - version string of the bundle
That is all the work required to create application bundle. On non-Mac OS-es, this looks just like ordinary folder. But, on Mac OS, it is treated differently, ie. as an application. Double clicking on a bundle in Finder will run the application.

Java runtime comes pre-installed on Mac OS X, so it's one less thing to worry about. On newer version, this may be removed and has to be installed manually, so it should be handled in startup script. But, it is out of the scope of this post.

4 comments:

  1. What do I put in the myapp.sh? Just this?

    java -jar myapp.jar

    ReplyDelete
    Replies
    1. Yes, that should do it. Just make sure it has executable permissions.

      Delete
  2. why not just deploy in any web server and let people download it using web start. This way you have more control on updating release or injecting new feature because Java web start will only download if you have new version.

    Thanks
    10 Java Enum Examples Developer should know

    ReplyDelete
    Replies
    1. That is always an option. However, this was more about desktop integration and giving end users OS consistent experience.
      Java applications have always been criticized for being "unnatural", so this series of posts was about a ways to circumvent this.

      Delete