Knowledge Base

Notice Information in this article applies to Excelsior JET version 10.0 and above.

APPLICABILITY

This article only applies to Excelsior JET for OS X.

SUMMARY

An OS X application bundle is a package (directory) with .app extension that contains the application's executable file, system configuration file (Info.plist), resources such as application icons and launch images, and any auxiliary files that the application itself needs for successful operation. It is a common way to distribute OS X applications.

This document contains instructions for packaging your natively compiled Java application into an OS X application bundle.

Control files for this article may be found in the Supplemental Downloads section.

PREREQUISITES

Self-contained directory

First of all, you need to compile your application with Excelsior JET and package it as a self-contained directory using JetPackII. For details, refer to the section “Step 5: Selecting a Back-End” in the Chapter “Deployment Automation” of the Excelsior JET User’s Guide.

Handling Process Serial Number Argument

OS X assigns a unique process serial number (PSN) to each application launched from an application bundle. The PSN gets passed to the application executable of a launched bundle as a command-line parameter. This means that the main method of your application should correctly handle a first argument of the form -psn_X_YYYYYY. One possible solution is to simply ignore all arguments if the first one starts with -psn_.

To check if your application meets this requirement, try to launch it from a terminal with a fake PSN argument and verify that everything works correctly with and without such argument:

$ cd /path/to/YourApp-native
$ ./YourApp -psn_0_111111
$ ./YourApp

Working Directory Independence

OS X starts an application bundle executable from an unpredictable working directory (depending on OS X version, it can be /, ~, application bundle root, or something else). Therefore you must ensure that your executable starts and works properly regardless of the operating system's choice of the current working directory at its launch.

To check if your application meets this requirement, try to start it from a terminal with the current working directory set e.g. to the root directory:

$ cd /
$ /path/to/YourApp-native/YourApp

If your application starts and works correctly, you may proceed to the next section. Otherwise you have two options:

  1. Modify the code of your application so that it no longer depends on being launched from a particular file system location (e.g. does not use paths relative to the current working directory).

  2. Tweak system properties to imitate start from the directory containing the executable.

    In JetPackII, select the application's executable on page “Resources” and add the following Java system properties:

    -Duser.dir=*{exe.dir}
    -Djet.cd.to.user.dir

    The first line sets the value of the user.dir system property equal to the full pathname of the directory where the executable is located. The second line contains a specical property recognized by the Excelsior JET VM.
    Its presence forces the process to change its current working directory to the value of the user.dir system property shortly upon startup, before control gets passed to the application's code.

    For details, refer to the subsection “Editing Java system properties” of the section “Step 2: Configuring Resources And System Properties” in the Chapter “Deployment Automation” of the Excelsior JET User’s Guide.

    Create a self-contained directory and recheck that your application is insensitive to the working directory.

APPLICATION BUNDLE CREATION

In the Supplemental Downloads section, you will find a simple shell script that automates the creation of an application bundle. That script does the following:

  • creates bundle's inner hierarchy,
  • generates an Info.plist file,
  • copies the required resources (your application and icon file).

NOTE: RCP application bundles exported from the Eclipse IDE are ready for signing and don't need to be converted with this script.

To create an application bundle, extract the createbundle.sh file from the downloaded archive and open it in a text editor. You have to uncomment a few required variable definitions at the top, specifying the desired values:

  • SHORT_NAME - name of the resulting application bundle. It is also shown when you hover over the application icon in the Dock.

  • LONG_NAME - general name of your application. It is shown in the left corner of the menu bar, in the list of applications in the Activity Monitor, and so on.

  • BUNDLE_ID - unique identifier of the application. To ensure uniqueness, it is recommended that you use a Java-package style identifier, such as com.example.myapp.

  • SCD - path to the self-contained directory produced by JetPackII.

  • EXE - name of your application executable file (Important: it has to be located in the root of the SCD directory.)

  • ICON_PATH - path to the directory with your application icon.

  • ICON_NAME - name of the icon of your application (it has to be located in the root of the ICON_PATH directory.)

    Note: The icon has to be in the Apple Icon Image format (*.icns).

  • VER - version of your application, as three dot-separated integers.

Save the script and run it from a terminal:

$ ./createbundle.sh

Upon its successful completion, you will find an application bundle called SHORT_NAME.app in the current working directory. You can open it from the Finder by double-clicking, or right from the terminal using the open command:

$ open SHORT_NAME.app

Please note that the provided script only helps you create the structure of the bundle and write main properties into its Info.plist file. Extra features, such as a custom URL scheme, should be implemented additionally.

More information about application bundle structure and Info.plist format may be found in the section “Anatomy of an OS X Application Bundle” of Apple Bundle Programming Guide.

Retina Displays

NOTE: If fonts in your application launched with the resulting bundle look fuzzy on Retina displays, add this key-value pair to the Info.plist file with the help of your favorite text editor:

<key>NSHighResolutionCapable</key>
<true/>

CODE SIGNING

IMPORTANT: Unless your application bundle is signed with a Developer ID certificate provided by Apple, it will not launch on OS X 10.8 and newer with default security settings.

Developer ID certificates can be obtained through the Member Center of the Apple Developer Program.

Refer to the Apple Code Signing Guide for in-depth information about the code signing process.

Signing Application Bundles

Once you have successfully created an application bundle, use the codesign utility to sign it with your Developer ID certificate, specifying, at a minimum, the following options:

codesign --verbose --force --deep --sign "<developer identity>" YourBundle.app

The --force option replaces existing signatures, if any, whereas the --deep option ensures recursive signing of the entire contents of the bundle.

For complete usage information, refer to the codesign man page.

Creating And Signing Bundle Packages

Bundle packages (.pkg files) are the preferable format for distribution of your applications through the Mac App Store and outside of it. They are created with the help of the productbuild utility:

productbuild --sign "<publisher identity>" \
             --component YourBundle.app [<install-path>] YourBundle.pkg

where <install-path> is an optional parameter that points to the default installation path on the target system.

After creating a package bundle, you can submit it to Mac App Store or publish it on your website.

The productbuild man page provides complete usage information for the utility.

REFERENCES

  1. Bundle Programming Guide (Apple documentation).

  2. Code Signing Guide (Apple documentation).

SUPPLEMENTAL DOWNLOADS

Article ID: 37
Last Revised On: 25-Sep-2015