7.3 Application Bundles

Native Mac OS X applications are delivered in packages known as application bundles. These packages contain the application's executable code, images, sounds, icons, localizable strings, and other resources. An application, as shown in the Finder, is actually just a specific directory structure with a few additional attributes.

These application bundles are displayed in the Finder with a simple name (for example, TextEdit). Users can double-click on these application names, complete with colorful icons, and the system automatically launches the application. Alternatively, users can drop documents on the application, and the launched application will attempt to open the selected document.

For a developer, however, an application bundle is a directory with an .app suffix and a specific internal file structure. You can explore these bundles on your system from the Finder by Control-clicking on an application and selecting "Show Package Contents," as shown in Figure 7-2.

Figure 7-2. Opening an application package

7.3.1 Layout of an Application Bundle

Once you peel back the layers of an application bundle, you'll find quite a few directories, each with several files. Figure 7-3 shows the structure of a typical application bundle for a Java application (in this case, the open source Java application PCGen; for more information on PCGen, visit http://sourceforge.net/projects/pcgen/).

Figure 7-3. Sample application bundle

If you installed NetBeans according to the instructions in Chapter 2, you saw another example of an application bundle.

The Info.plist file in the Contents folder is probably the most significant element of any Mac OS X application. For Java applications, this file is used to specify information for the JVM execution of the application.

Icons for the Mac OS X Finder are placed in the Resources folder. The preferred format is the proprietary Mac OS X file type designated by the .icns suffix, as this file type includes support for different bit depths and icon sizes in a single file. Use the Icon Composer application installed in /Developer/Applications to create icon files, or investigate online for freeware and shareware tools that accomplish the same task.

Your Java code, in either JAR or class files, is put into Resources/Java. A native executable file in the MacOS folder launches the appropriate classes. This native stub library, referenced by the Info.plist file, is the component that actually launches the application.

While understanding all of these steps is useful (especially in an automated build environment), a couple of different tools allow you to set up and work with application bundles without having to work through these details manually. One tool, MRJAppBuilder, is included with Apple's tool set. This chapter covers this tool in more detail later.

7.3.2 Property List Attributes for Java Applications

Before digging into specific tools, though, you need to understand the Info.plist file that keeps coming up. In fact, by browsing through applications and various configuration directories on Mac OS X, you'll notice the frequent use of XML files with a .plist extension. These files are called property lists, and can be edited easily with the bundled Mac OS X Property List Editor (as shown in Figure 7-4).

Figure 7-4. Mac OS X Property List Editor

The Info.plist file in a Mac OS X application's Contents folder is no different from these other property lists. While you can use tools to generate these files, try to understand what was created for you and how to modify the auto-generated files.

Since the various .plist files are in XML, you can modify them with any text editor. The Property List Editor is generally a better option, though, as it ensures that you maintain well-formed XML.

Example 7-2 shows an example property list for the SimpleEdit application created in Chapter 4.

Example 7-2. Info.plist for SimpleEdit
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" 
<plist version="1.0">
            <string>Text File</string>

</plist> About dictionaries

This property list is divided into hierarchical dictionaries. The top-level dictionary contains the information that the operating system needs to launch the application. The keys in this section are prefixed by CFBundle and are more or less self-explanatory. One exception is CFBundleDocumentTypes , which tells the system that this particular application will open any file as a text document by default. Identifying files in this manner lets users drag and drop files on your application's icon, either in the Finder or the Dock. You'll want to create a new file type and extension if you want to handle custom data file types. Finally, you should set the proper options for the Java dictionary. CFBundle dictionary keys

Per Apple's documentation (installed at /Developer/Documentation/Essentials/SystemOverview/PropertyListKeys/Bundle_Keys.html), the keys in Table 7-1 are used to build Java applications. The comments shown below are based on Apple's documentation. Keys not used by Java applications have been omitted.

Table 7-1. CFBundle dictionary keys








The native region for the bundle. Usually corresponds to the author's native language.




The bundle's localized display name.




An array of dictionaries describing the document types supported by the bundle. For more information, see the next section.




Name of the bundle's executable file.




A string for displaying richer (HTML) content in the Finder's "Get Info" panel.




A string for display in the Finder's "Get Info" panel.




The filename for an icon image file.




A unique identifier string for the bundle. This string should be in the form of a Java package name, such as com.apple.myapp.




Version information for the Info.plist format.




The short display name of the bundle. Should be less than 16 characters.




The four-letter code identifying the bundle type. For applications (including Java applications) you should set this value to "AAPL".




The marketing-style version string for the bundle




The four-letter code identifying the bundlecreator.




The executable's build number. CFBundleDocumentTypes dictionary keys

Per Apple's documentation (installed at /Developer/Documentation/Essentials/SystemOverview/PropertyListKeys/Bundle_Keys.html), the keys in Table 7-2 describe the kinds of documents that your application supports.

Table 7-2. CFBundleDocumentTypes dictionary keys






This key contains an array of filename extensions that map to this type. To open documents with any extension, specify an extension with a single asterisk (*). This key is required.



This key specifies the name of the icon file to be used when displaying documents of this type. The icon filename can have an extension or be without one. If it is without an extension, the system appends an extension appropriate to the platform (for example, .icns in Mac OS 9).



This key contains the abstract name for the document type and is used to refer to the type. This key is required and can be localized by including it in the corresponding InfoPlist.strings files. This value is the main way to refer to a type, and it is recommended that you use a Java-style package identifier to ensure its uniqueness. If the type is a common Clipboard type supported by the system, you can use one of the standard types listed in the NSPasteboard class description.



This key contains an array of four-letter type codes that map to this type. To open documents of any type, specify the four-letter type code `****'. This key is required.



This key specifies the application's role with respect to the type. The value can be Editor, Viewer, Printer, Shell, or None. This key is required.

Generally, most Mac OS X Java applications work with document types based on file extension (as opposed to the four-letter creator codes), as file extensions survive cross-platform exchange. Therefore, to support a launch of your application types, register the file extensions that your application supports (for example, .txt, .gif, .jpg, and .jpeg). It's usually best to err on the side of supporting a larger variety of document file extensions and file types for the purposes of receiving Finder notifications (relying on the wildcard options above). Then you should perform error checking on the data files from within your application.

For more information on how your Java application is notified of opening files, see Chapter 5. Java dictionary keys

At the end of the CFBundle keys, a Java key designates the beginning of the Java dictionary. Two top-level keys in the Java dictionary are required in the property list of a Java application bundle:


This key value should be set to the fully qualified class name of the application's main entry method. The value of this key can be retrieved at runtime by querying the com.apple.mrj.application.main system property.


This key lets you set the classpath for your application. The string value for this key should specify the fully qualified path to the directories where your class files are, or to your JAR files. You'll note the use of the $JAVAROOT variable to point to the Resources/Java directory. If your application bundles third-party JAR files, you'll want to include them here and reference them with the $JAVAROOT variable. You can discover this value by querying the com.apple.mrj.application.classpath system property.

In addition to these required keys, you may wish to specify additional keys in the Java dictionary:


This value is tokenized into a String array, and passed into the application's main( ) method. This can be a convenient way to package applications that expect specific command-line arguments. This value can be introspected through the com.apple.mrj.application.parameters system property.


When an application is launched, this key sets the working directory. By default, the current working directory is set to the application bundle's parent directory. You can use the $APP_PACKAGE variable to refer to the root of the application bundle. The value of this key is available via introspection through the com.apple.mrj.application.workingdirectory system property.

You may prefer to use the standard Java APIs for determining the user's home and working directory. This has the added flexibility of adapting to changes the user makes to the working directory while the application is running.


The space-delimited value of the VMOptions key can set the JVM options normally referred to by the -X and -XX options. The typical use of this key is to set the minimum and maximum heap size for the JVM launching the application. Your application can read this value by looking at the com.apple.mrj.application.vm.options system property.


This can be used to specify either a specific version of the JVM to use (e.g., "1.3.1" or "1.4.1") or the latest version in a series (e.g., "1.3+" or "1.4+"). Note that even if the user has installed JDK 1.4.1, your application will default to the latest JDK 1.3 JVM.

This means that if you are building an application that requires JDK 1.4.1 or later, be sure to include the JVMVersion key! The Properties dictionary

The keys in the Properties dictionary include both Mac OS X-specific options and general Java options. Mac OS X-specific keys and values that you may add to this dictionary of the property list include:


This property defaults to true. It turns on hardware graphics acceleration for the video cards not commented out of the /Library/Java/Home/lib/hwexclude.properties file. If it is set to false, hardware acceleration is turned off. You can use it in conjunction with the com.apple.hwaccelexclude property.


This property defaults to none. When specific video card designation strings are passed in with this property, hardware graphics acceleration is not turned on for the specified video cards. When this property is set, /Library/Java/Home/lib/hwexclude.properties is ignored.

This property is useful when you know that specific video cards (hopefully just one or two) cause problems with your application when hardware acceleration is turned on. You are testing for this, right?


This property defaults to false. When set to true, it causes java.awt.FileDialog to show application packages (with both .app and .pkg extensions) as if they were files, prohibiting the user from selecting specific files inside the application bundle. This option is not available for use on JDK 1.4.1.


This property defaults to false. Setting it to true causes Swing menus that use the Aqua look and feel to appear in the global application menu bar at the top of the screen (instead of inside the window). This is the proper behavior for Mac OS X applications, but may require some testing before your application supports it properly. Note that JMenuBars in JDialogs are not moved to the Mac OS X menu bar. Under JDK 1.4.1, use apple.laf.useScreenMenuBar instead. Note that you can include both properties with no ill effects.


This property is not defined by default. If defined and set to true, tab controls in Swing applications more closely resemble the Metal look and feel (which can be very helpful if your application expects smaller tabs). If the property is set to false, the tabs assume a larger size that is similar to the default Aqua controls. This option is not available for use on JDK 1.4.1.


This property defaults to true. When rendering text, it tells the application to use anti-aliasing. Occasionally you might want to switch this value to false. If your application draws text to the same location twice, it can look blurry, as each application of the text to the screen is incrementally darker. Conversely, if your application expects to erase text by drawing the background color over previously rendered text, anti-aliasing artifacts can be left over. Under JDK 1.4.1, use apple.awt.textantialiasing instead (as described in the next section). Note that you can include both properties with no ill effects.


This property also defaults to true. Like the potential issues around anti-aliased text, the default Mac OS X rendering of graphics can lead to blurry graphics. You may see a small performance increase by setting this property to false.


If defined, this property adds an "About" command to the top of the application menu. Your application can be notified when the user selects this menu item by registering a com.apple.mrj.AboutHandler, as described in Chapter 5.


This property defaults to true and causes a growbox (a resizing control) to intrude into AWT frames. For certain applications, this growbox can obscure other important GUI features, such as scrollbars. If turned off (by setting the value to false), the bottom of the window is pushed down 15 pixels. Setting this value to false is appropriate only as an intermediate stopgap?you are strongly encouraged to rework your application's user interface so the growbox control looks natural and doesn't block other important controls. Under JDK 1.4.1, use apple.awt.showGrowBox instead. Note that you can include both properties with no ill effects.


This property defaults to false, but setting it to true enables live resizing of windows. You should test this property on a variety of machines (and perhaps make it a user-configurable preference), as the performance of live window resizing for your application can vary dramatically between different systems and JVMs. This option is not available for use on JDK 1.4.1.


Allows you to specify that your main application window should use the brushed Metal appearance, similar to that used by Apple applications such as iTunes and Safari. This is set to false by default. It is available only on JDK 1.4.1. JDK 1.4.1 rendering

JDK 1.4.1 introduces more sophisticated control over rendering via Java 2D. For more information on Java 2D, examine the standard Java documentation on java.awt.Graphics2D . In the section below, references are made to various rendering hints via settings such as KEY_ANTIALIASING and KEY_TEXT_ANTIALIASING?these are references to the Java 2D APIs.

The following properties are available only when using JDK 1.4.1 or a later JVM.


Specifies that standard graphic primitives (such as line, arc, rectangle, etc.) are drawn anti-aliased. By default, text will also take this setting, but you can override that using apple.awt.textantialiasing. You can override this setting via the KEY_ANTIALIASING rendering hint for specific objects. By default this is set to false for Metal applications, and to true for Aqua applications. Even if it is set to false, standard Aqua user interface components will still be drawn anti-aliased.


Sets the default Java 2D rendering hint for KEY_TEXT_ANTIALIASING. Although this inherits the same setting as apple.awt.antialiasing, you can override that setting explicitly. The default value is false unless you are using the Aqua look and feel.


Determines whether Graphics 2D objects prioritize speed or quality. It sets the Java 2D hint KEY_RENDERING so that it accepts either VALUE_RENDER_SPEED or VALUE_RENDER_QUALITY as an argument.


Allows you to set the Java 2D KEY_INTERPOLATION rendering hint to determine which algorithm is used in image transformations. Options include VALUE_INTERPOLATION_NEAREST_NEIGHBOR, VALUE_INTERPOLATION_BILINEAR, and VALUE_NTERPOLATION_BICUBIC.


Allows you to specify that the Java 2D KEY_FRACTIONALMETRICS hint should use floating-point font metrics instead of the default integer metrics. Options include VALUE_FRACTIONALMETRICS_ON and VALUE_FRACTIONALMETRICS_OFF. JDK 1.4 full screen display

JDK 1.4 introduces the ability to run your application in "full screen" mode, where the application takes over the entire screen, hiding default user interface elements such as the menu bar. This can be particularly useful for such applications as kiosk displays and games.


This flag causes full screen applications to be displayed in a window. You may wish to make this a user preference, or use it to assist with debugging. The default value is false.


When you have multiple displays, entering full screen mode darkens any secondary screens that might be attached to the system. Setting this to false overrides this default behavior so that secondary screens are not darkened (allowing you to still see the content displayed, such as debugging output or logs). The default value is true.


Hides the mouse cursor when in full screen mode. Many entertainment applications, such as games, may wish to hide the mouse. The default value is true.


Mac OS X automatically provides a "fade" effect when changing screen resolutions. You may find it more aesthetically pleasing to see this fade effect whenever you switch to full screen mode, even if you don't initiate a resolution change. To do this, set this property to true instead of the default value of false. JDK 1.4 window positioning

In the JDK 1.4 release, Apple provides additional functionality to assist with window positioning. This is particularly useful for when you store the current window position, and the user changes the screen to a smaller resolution?the window may no longer appear on screen! This functionality is controlled via the following properties:


New windows are always created on screen, not outside the desktop where users would not be able to access them. The default value is false.


This option disallows users from moving windows into a position where they would no longer be able to access them. The default value is false.

You can test any of these options from the command line by using the -D option to the java command. For example, if you want to run an application with standard Aqua menu styles and the name "SimpleEdit", you could pass in two keys, com.apple.macos.usescreenmenubar and com.apple.mrj.application.apple.menu.about.name, as shown here:

java -Dcom.apple.macos.useScreenMenuBar=true

If you get the results that you expect, you can then add these two properties into your Properties dictionary in the Info.plist file. Using the -D option allows you to test options quickly before editing your property lists.

7.3.3 Why Use Application Bundles?

Using double-clickable JAR files is easy, so why bother with application bundles? Bundles require a lot of properties to be set, and it takes time to get used to property lists. However, you can benefit from packaging your application as a Mac OS X application bundle:

  • The application launches on a double-click (as a JAR file would).

  • The application becomes a single, self-contained structure that is portable across different filesystems.

  • You can optionally specify a custom icon to appear in the Dock and the Finder.

  • You can set specific system properties to more closely emulate the behavior of a native application.

  • You can bind specific document types to the application. The Finder keeps track of which applications can open which documents and document types, which lets users double-click on a document in the Finder to open your application, drag and drop a document on your application, or use the "Open With" command in the Finder.

    To take full advantage of document type bindings, implement the document event handlers in your application as described in Chapter 5.

  • You can set specific configuration and runtime details that would otherwise require the user to enter a complex command-line command (such as memory configuration or default file encoding).