Java on Mac OS X

8/1/05

The implementation of Java on Mac OS X is not exactly the same as on other platforms. There are differences.

Java 1.3.x corresponds to OS X 10.2, Java 1.4.2 corresponds to 10.3. Under 10.3, however, both Java 1.3 and 1.4.2 are both installed simultaneously.

Components of JRE in OS X are built on native Mac OS X technologies.

Components on OS X include: deployment technologies, UI tools, integration APIs, core APIs, JVM, JRE, Java SDK. JRE is built into OS X and there is no need to install any additional software.

The Java 1.4.1 release includes a complete reworking of how Java is implemented for Mac OS X. This release is more than just an update from the Java 1.3.1 classes to the Java 1.4.1 classes. It is more integrated with both the Java Software Development Kit and the core operating system than the Java 1.3.1 implementation. Apple has been able to bring Java 1.4.1 to Mac OS X using about two-thirds less native classes than the 1.3.1 implementation required.

Before developing with Java 1.4.1 on Mac OS X, it is important to note a few basic details:

• The Java version is 1.4.1_01.

• The Java 1.4.1 runtime environment requires Mac OS X version 10.2.3 or later.

Java 1.4.1 is not included as a part of Mac OS X by default. If you are writing Java 1.4.1 applications remember that users will need to download Java 1.4.1 from Apple before they can use your application. They may do this through the Software Update pane of System Preferences or manually from http://www.apple.com/downloads/macosx/. Apple does not provide redistribution licenses for the Java 1.4.1 implementation.

• The Java 1.4.1 Developer Package requires the December 2002 version of the Mac OS X Developer Tools to be installed. Both the Java 1.4.1 Developer Package and the December 2002 Mac OS X Developer Tools are available online at http://connect.apple.com.

• J2EE 5 requires Mac OS X 10.4.5 or later.

Java Swing apps in OS X use the Aqua look and feel (LAF). To use the Metal LAF, modify your code to include UIManager.setLookAndFeel(javax.swing.plaf.metal.MetalLookAndFeel).

 

Java Reference Library

Mac OS X Java Frequently Asked Questions

Apple Java Release Notes

Technical Q&As Java List

 

Finding Your Way Around

Since Java is built into the operating system, it is implemented as a Mac OS X framework.

The code that makes the Java implementations in Mac OS X work can be found in /System/Library/Frameworks/JavaVM.framework/.

The CurrentJDK (in OS X 10.3) symlink points to the 1.4.2 directory. This is where the code that actually implements Java 1.4.2 resides.

The only directories that you should be concerned with are the Commands, Home, and Headers directories. Even for these, there are restrictions on how you use their contents in the proper way. You should never count on specific paths to anything in these directories for code that you ship to customers.

You should also never write anything into these directories on a user’s system. Although you can see what is there, consider the contents of /System/Library/Frameworks/JavaVM.framework/ as read only, and recognize that the contents may change with updates to Java or the operating system.

There are times that you want to install JAR files or JNI libraries into the Java home directory, or would expect to link against a header file there. How do you do that if you are not supposed to write into the JavaVM.framework directory or link specifically against paths in there? Apple provides a way to do this that should be stable across Java or operating system updates in /Library/Java/.

Some applications look for Java’s home directory (JAVA_HOME) on the users system, especially during installation. If you need to explicitly set this, in a shell script or an installer, set it to /Library/Java/Home/. Setting it to the target of that symbolic link can result in a broken application for your customers. Programatically you can use System.getProperty("java.home"), as you would expect.

/Library/Java/Home/ also contains the /bin/ subdirectory where symbolic links to command-line tools like java and javac can be found. These tools are also accessible through /usr/bin/.

Note: Since the links in /usr/bin/ point to the tools for Java 1.4.2, to invoke Java 1.3.1 tools you must use the full path. For example, to run the Java 1.3.1 version of java use /System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Commands/java.

Java can be extended by adding custom.jar, .zip, and .class files, as well as native JNI libraries, into an extensions directory. On some platforms this is designated by the java.ext.dir system property. In Mac OS X, put your extensions in /Library/Java/Extensions/. Java automatically looks in that directory as it is starting up a VM.

Putting extensions in /Library/Java/Extensions/ loads those extensions for every user on that particular computer. If you want to limit which users can use certain extensions, you can put them in the /Library/Java/Extensions/ directory inside the appropriate users’ home directories. By default that folder does not exist, so you may need to make it.

When you launch a Java application from the command line, standard output goes to the Terminal window. When you launch a Java application by double-clicking it, your Java output is displayed in the Console application in /Applications/Utilities/.

The default filesystem of Mac OS X, HFS+ (Mac OS Extended format), is case-insensitive but case-preserving.You should make sure that no files in the same directory have names that differ only by case.

 

Development Tools

The command-line tools that Sun provides as part of the Java SDK for Linux and Solaris should work the same in Mac OS X as they do on those platforms. There are only a few significant distinctions between the standard Java development tools in Mac OS X and those found on other UNIX-based platforms:

• The installed location of the command-line tools is different in Mac OS X. The tools are installed with the rest of JavaVM.framework in /System/Library/Frameworks/. Symbolic links are provided from /usr/bin/ to these tools.

• Tools.jar does not exist. Scripts that look for this file to find the SDK tools need to be rewritten.

The most current version of the documentation is always available from the Java Reference Library on the Apple Developer Connection website.Man pages for the command-line tools are accessible from the command line man program and through Xcode’s Help menu. Apple’s documentation aims to augment Sun’s documentation for Java development issues specific to Mac OS X and to document Mac OS X–specific features of Java.

See the Introduction to Project Builder Section near the end of this document for more info on devlopment tools.

 

Java Deployment Options in Mac OS X

When deploying Java applications in Mac OS X, you have access to the Java Plug-in and Java Web Start as you do on other platforms. There are also two additional deployment technologies in Mac OS X. You may deploy applications as double-clickable JAR files or as native Mac OS X application bundles.

Double-Clickable JAR Files

If your application has a graphical interface and will be run by general users, you should consider wrapping the JAR file as a Mac OS X application bundle. Double-clickable JAR files launch with Java 1.4.2. If a JAR file needs to be launched in Java 1.3.1, wrap the JAR file as a Mac OS X application bundle using Jar Bundler.You can double-click on a Java class file to launch your application, but this is not a recommended method for application deployment.

If you choose to deploy your application from a JAR file in Mac OS X, the manifest file must specify which class contains the main method. Without this, the JAR file is not double-clickable and users see an error message.

If you have a JAR file that does not already have the main class specified in the manifest, you can remedy this as follows:

1. Unarchive your JAR file into a working directory with some variant of jar xvf myjar.jar.

2. In the resultant META-INF directory is a MANIFEST.MF file. Copy that file and add a line that begins with Main-Class: followed by the name of your main class. For example, a default manifest file in Mac OS X looks like this:

Manifest-Version: 1.0
Created-By: 1.4.2_05 (Apple Computer, Inc.)

With the addition of the main class designation it looks like:

Manifest-Version: 1.0
Created-By: 1.4.2_05 (Apple Computer, Inc.)
Main-Class: YourAppsMainClass

3. Archive your files again but this time use the -m option to jar and designate the relative path to the manifest file you just modified, for example, jar cmf YourModifiedManifestFile.txtYourJARFile.jar*.class

If a JAR file has a main class specified in its manifest file, a user can launch it just by double-clicking the JAR file. Double-clickable JAR files are run with Java 1.4.1. If you need to run a JAR file with Java 1.3.1, you can either wrap it as a Mac OS X application bundle using Jar Bundler or you can launch it from the command line with /System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Commands/java -jar YourJARFile.jar.

Mac OS X Application Bundles

When deploying Java applications in Mac OS X, consider making your Java application into a Mac OS X application bundle. It is easy to do and offers many benefits:

• Users can simply double-click the application to launch it.

• If you add an appropriate icon, it shows the application icon in the Dock and in the menu bar, clearly identifying your application.

• It lets you easily set Mac OS X–specific system properties that can make your Java application hard to distinguish from a native application.

• You can bind specific document types to your application. This lets users launch your application by double-clicking a document associated with it.

Applications bundles for Java applications should have the following components:

• An Info.plist file in the Contents folder. In the case of a Java application, this contains some important information that Mac OS X uses to set up the Java runtime environment for your application. More information about these property lists is in Java 1.4 Info.plist Java Dictionary Keys.

• A file named PkgInfo should also be in the Contents folder. This is a simple text file that contains the string AAPL optionally followed directly by a four letter creator code. If an application does not have a registered creator code, the string AAPL???? should be used. You may register your application with Apple’s creator code database on the ADC Creator Code Registration site at http://developer.apple.com/datatype/.

• The application’s icon that is displayed in the Dock and the Finder should be in the Resources folder. There is a Mac OS X–specific file type designated by the .icns suffix, but most common image types work. To make an icon (.icns) file from your images, use the Icon Composer application installed in /Developer/Applications/Utilities/.

• The Java code itself, in either jar or .class files, in Resources/Java/.

• A native executable file in the MacOS folder that launches the Java VM.

• Optional localized versions of strings may be included in folders designated by the .lproj suffix. The example in Figure 3-3 includes localizable strings for four different languages. See “Additional Considerations for Non-English Applications” for more information on localized application bundles.

The Info.plist file lets you fine-tune how well your application is presented in Mac OS X. With slight tweaking of some of the information in this file, you can make your application virtually indistinguishable from a native application in Mac OS X, which is important for making an application that users appreciate and demand.

If you build your Java application in Xcode or Jar Bundler, the Info.plist file is automatically generated for you. If you are building application bundles through a shell or Ant script, you need to generate this file yourself. Even if it is built for you, you may want to modify it. Since it is a simple XML file, you can modify it with any text editor.

A property list file is divided into hierarchical sections called dictionaries. These are designated with the dict key. The top-level dictionary contains the information that the operating system needs to properly launch the application.The keys in this section are prefixed by CFBundle and are usually self explanatory.

At the end of the CFBundle keys, this example includes a Java key designating the beginning of a Java dictionary. At least two keys should be in this dictionary; the MainClass is required and the JVMVersion key is highly recommended. A listing of all the available keys and Java version values for the Java dictionary is provided in Java 1.4 Info.plist Java Dictionary Keys.

If you examine an older Java application distributed as an application bundle, some of the keys may be missing from the Properties dictionary. Java application bundles used to include the Java-specific information distributed between an Info.plist file and another file, MRJApp.properties in Contents/Resources/ in the application bundle. If you are updating an existing application bundle, you should move the information from the MRJApp.properties file into the appropriate key in the Java dictionary in the Info.plist file.

Making a Java Application Bundle

There are three ways to make a Java application bundle:

• With Xcode
• With Jar Bundler
• From the command line

If you build a new Java AWT or Swing application, use one of Xcode’s templates and Xcode automatically generates an application bundle complete with a default Info.plist file. You can fine-tune the behavior of this application by modifying the Info.plist file directly in the Products group of the Files pane or by modifying the settings in the Info.plist Entries section of the Targets pane.

If you want to turn your existing Java application into a Mac OS X Java application, use the Jar Bundler application available in /Developer/Tools/. It allows you to take existing .class or jar files and wrap them as application bundles.

To build a valid application bundle from the command-line, for example in a shell script or an Ant file, you need to follow these steps:

1. Set up the correct directory hierarchy. The top level directory should be named with the name of your application with the suffix .app.

There should be a Contents directory at the root of the application bundle. It should contain a MacOS directory and a Resources directory. A Java directory should be inside of the Resources directory.

The directory layout should look like this

YourApplicationName.app/Contents/MacOS/
YourApplicationName.app/Contents/Resources/Java/

2. Copy the JavaApplicationStub file from /System/Library/Frameworks/JavaVM.framework/Versions/Current/Resources/MacOS/ into the MacOS directory of your application bundle.

3. Make an Info.plist file in the Contents directory of your application bundle. You can start with an example like that given in Listing 3-1 and modify it or generate a completely new one from scratch. Note that the application bundle does not launch unless you have set the correct attributes in this property list, especially the MainClass key.

4. Make a PkgInfo file in the Contents directory. It should be 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.

5. Put your application’s icon file into the Contents/Resources/ directory. (For testing purposes, you can copy the generic Java application icon from /Developer/Applications/Jar Bundler.app/Contents/Resources/.)

6. Copy your Java .jar or .class files into /Contents/Resources/Java/.

7. Set the bundle bit Finder attribute with SetFile, found in /Developer/Tools/. For example, /Developer/Tools/SetFile -a B YourApplicationName.app.

After these steps, you should have a double-clickable application bundle wrapped around your Java application.

Additional Considerations for Non-English Applications

To run correctly in locales other than US English, Java application bundles must have a localized folder for each appropriate language inside the application bundle. Even if the Java application handles its localization through Java ResourceBundles, the folder itself must be there for the operating system to set the locale correctly when the application launches. Otherwise Mac OS X launches your application with the US English locale.

Put a folder named with the locale name and the .lproj suffix in the application’s Resources folder for any locale that you wish to use. For example if you include a Japanese and French version of your application, include a Japanese.lproj folder and a French.lproj folder in YourApplicationName.app/Contents/Resources/. The folder itself can be empty, but it must be present.

By default, existing Java applications that have been bundled as native applications run with the Java 1.3.1 VM. As such, they exhibit the same behavior as they did before installing Java 1.4.1. This behavior provides the cleanest user experience. From a user’s perspective, an application continues to work the same way it has always worked. This is important since, from the user’s perspective, the application is not necessarily a Java application, but rather a Mac OS X application.

You may determine that you want users to run your existing applications with Java 1.4.1 instead of Java 1.3.1, perhaps to take advantage of new features in the 1.4.1 version. In that case it is your responsibility to designate the appropriate version of Java for your application. You can do this by modifying the Info.plist file of the native application bundle.

Note: Even if you do not need to take advantage of Java 1.4.1, you should update your application bundle to note which version of Java you want your application to run with. Although Mac OS X version 10.2 chooses to use Java 1.3.1 if none is specified, future versions of Java or the operating system may choose otherwise.

For new applications, set the VM version in the Build Information pane of Jar Bundler, or the Pure Java-Specific pane in Project Builder’s target editor. If you are modifying an existing application, modify the JVMVersion property in the Info.plist file. This file is in the Contents folder of the application bundle. To view this file in the Finder, Control-click the application icon, then choose “Show Package Contents.”

The Info.plist file is an XML document, so you can modify it with any text editor. If there is not already a key for JVMVersion, you need to add one. This key should be in the Java dictionary. For example, the Java section of the Info.plist might look something like this:

Info.plist without JVMVersion property:

< key>Java</key>    
  <dict>  
    <key>MainClass</key>
    <string>YourApplication</string>
    <key>ClassPath</key>
    <string>$JAVAROOT/YourApplication.jar</string>
  <dict>  

At the same level as the existing key and string combination for the ClassPath, add in a key value of JVMVersion and a string value from Table 3-1 as appropriate. The resulting Info.plist should look something like this:

Info.plist with JVMVersion property

< key>Java</key>    
  <dict>  
    <key>MainClass</key>
    <string>YourApplication</string>
    <key>JVMVersion</key>
    <string>1.4+</string>
    <key>ClassPath</key>
    <string>$JAVAROOT/YourApplication.jar</string>
  <dict>  


Designations for particular versions of Java in Mac OS X version 10.2

Value Java version used Notes
1.3.1
1.3.1 Specifies an exact version of Java.
1.3* 1.3.1 Requests the highest version of Java 1.3 available. Note that if Java 1.3 is updated in future releases of Mac OS X the highest version of Java 1.3 will be used.
1.3+ 1.4.1 Requests the highest version of Java above 1.3. Note that if Java is updated in future releases of Mac OS X, the highest numbered version will be used.
1.4.1 1.4.1 Specifies an exact version of Java.
1.4* 1.4.1 Specifies the highest version of the Java 1.4 available. Note that if Java 1.4 is updated in future releases of Mac OS X the highest version of Java 1.4 will be used.
1.4+ 1.4.1 Specifies the highest version of Java above 1.4. Note that if Java is updated in future releases of Mac OS X, the highest numbered version will be used.

Some older applications may have an MRJApp.properties file instead of an Info.plist file. For these applications, add the following line with value set to an appropriate value from Table 3-1: com.apple.mrj.application.JVMVersion=value.

 

Command Line Applications

Running Java from the command line runs Java 1.4.1. The Java commands in /usr/bin are linked to the most current version of Java tools on the system. In this release they are linked to commands in /System/Library/Frameworks/JavaVM.framework/Versions/1.4.1/Commands. If you need to run the Java 1.3.1 version of a command line Java tool, you may do so by explicitly calling the appropriate Java 1.3.1 command in /System/Library/Frameworks/JavaVM.framework/Versions/1.3.1/Commands.

If you are building shell scripts for distribution to customers that link to a specific version of a Java command in /System/Library/Frameworks/JavaVM.framework you should consider wrapping your application as a Mac OS X application with Jar Bundler. Specifying a specific path in the operating system (other than /usr/bin) is not the most robust solution since changes to Mac OS X may render these paths obsolete and your application broken.

 

Java Applets

Java Applets cannot choose which version of Java they invoke. This choice is made instead by the browser. Microsoft’s Internet Explorer uses Java 1.3.1. Apple’s Safari uses Java 1.4.1. (Applet Launcher also uses Java 1.4.1.)

 

Java Web Start

As a part of Java 1.4.2, Mac OS X also supports deploying your application as a Java Web Start application. Java Web Start is an implementation of the Java Network Launching Protocol & API (JNLP) specification, which means that if you make your application JNLP-aware, Mac OS X users do not need to do anything to use it. They have access to your applications through the Web browser and the Java Web Start application (installed in /Applications/Utilities/Java/).

J2SE 1.4.1 on Mac OS X includes Java Web Start 1.2

By default, if a user launches a Java Web Start application more than twice from the same URL, they are prompted to save the application as a standard Mac OS X application, as shown in Figure 3-4. They are also prompted on where they want to save your application. The application is still a Java Web Start application, with all the benefits that offers, but it is now easier for users to run your application since they do not have to launch a Web browser or the Java Web Start application.

The desktop integration setting can be changed in the Preferences of the Java Web Start application in /Applications/Utilities/Java/.

You need to be aware of only a few details about how the Mac OS X implementation of Java Web Start differs from the Windows and Solaris versions:

• It does not support downloading of additional Java Runtime Environments (JREs). Mac OS X version 10.3 includes J2SE 1.3.1 and either J2SE 1.4.1 or J2SE 1.4.2. If your JNLP-based application needs Java 1.4.2, you must inform your customers that if they don’t already have it, they need to download it through Software Update or get it from http://www.apple.com/downloads/macosx/. The version keys that are valid for Java Web Start applications are the same as those for Mac OS X application bundles and are listed in Java 1.4 Info.plist Java Dictionary Keys.

• It is not necessary to set up proxy information explicitly in the Web Start application. Java Web Start in Mac OS X automatically picks up the proxy settings from the Network pane in System Preferences.

• Java Web Start caches its data in the user’s /Library/Caches/Java Web Start/cache/ directory. In Mac OS X 10.1 Java Web Start caches its data in your login directory in the hidden directory .javaws.

Java Web Start applications follow the guidelines laid out for standard JNLP-based applications. Your JNLP file should specify a J2SE Version key. This key is evaluated to determine whether to run your application with Java 1.3.1 or Java 1.4.1.

If you do not specify a value for the j2seversion key, Java 1.3.1 is used by the application.

When a user runs the same Java Web Start application multiple times, Mac OS X provides the option of building a native application bundle around that application. With this release of Java 1.4.1 these application bundles always launch with Java 1.3.1 regardless of what the JNLP file says.

 

The Java Plug-in

Java 1.4.2 for Mac OS X includes the Java Plug-in for you to deploy applets in browsers and other Java embedding applications. The only browsers that currently support the Java 1.4.2 Java Plug-in use the Web Kit API. Other browsers on Mac OS X currently use either a Java 1.3.1 Java Plug-in or the legacy Java Embedding framework. The Java Embedding framework supports Java 1.3.1 by implementing the appletviewer class and therefore does not provide the added benefits that the Java Plug-in provides like JAR caching, handling of signed JAR files, and the Java console.

When testing your applications, you can determine which version of the Java Plug-in the application is using with the GetOpenProperties applet available from Sun at http://java.sun.com/docs/books/tutorial/applet/practical/properties.html.

These are the Java implementations used by current browsers:

Safari 1.2
Java 1.4.2 Plug-in

Internet Explorer 5.2
Java 1.3.1 Embedding framework

Netscape 7.2/ Mozilla 1.7
Java 1.3.1 Plug-in

Camino 0.8
Java 1.3.1 Plug-in

The Applet Launcher application in /Applications/Utilities/Java/ also uses the Java 1.4.2 Plug-in, but it is not a full-featured browser – it is more of a development tool. For more information on Applet Launcher see “Applet Launcher”.

For all of the common browsers, the <APPLET> tag has proven to be less problematic than the <OBJECT> and <EMBED> tags.

User Interface Toolkits

The Mac OS X implementation of the Swing, AWT, accessibility, and sound user interface toolkits differ from other platforms. Although there is some additional functionality in Mac OS X, for the most part these toolkits work as you would expect them to on other platforms.

 

Swing

In Mac OS X, Swing uses apple.laf.AquaLookAndFeel as the default look and feel (LAF). Swing attempts to be platform neutral, but there are some parts of it that are at odds with the Aqua user interface. Apple has tried to bridge the gap with a common ground that provides both developers and users an experience that is not foreign.

While testing your application, you might want to test it on the standard Java Metal LAF as well as Aqua. To run your application with Metal, pass the -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel flag to java.

Macintosh users expect to find their menus in the same spot – no matter what window they have open – at the top of the screen in the menu bar. In the default Metal LAF, as well as the Windows LAF, menus are applied on a per-frame basis inside the window under the title bar.

To get menus out of the window and into the menu bar you need only to set a single system property:
apple.laf.useScreenMenuBar. This property can have a value of true or false. By default it is false, which means menus are in the window instead of the menu bar. When set to true, the Java runtime moves any given JFrame’s JMenuBar to the top of the screen, where Macintosh users expect it. Since this is just a simple runtime property that only the Mac OS X VM looks for, there is no harm in putting it into your cross-platform code base.

Note that this setting does not work for JDialogs that have JMenus. A dialog should be informational or present the user with a simple decision, not provide complex choices. If users are performing actions in a dialog, it is not really a dialog and you should consider a JFrame instead of a JDialog.

Another example of a difference in Mac OS X is with JTabbedPanes. With other LAFs, if you have JTabbedPane with too many tabs to fit in the parent window – they just get stacked on top of each other. In the Aqua user interface of Mac OS X, tab controls are never stacked. The Aqua LAF implementation of multiple tabs includes a special tab on the right that exposes a pull-down menu to navigate to the tabbed panes not visible. This behavior allows you to program your application just as you would on any other platform, but provides users an experience that is more consistent with Mac OS X. One other thing to keep in mind about JTabbedPanes in the Aqua look and feel is that they have a standard size. If you put an image in a tab, the image is scaled to fit the tab instead of the tab to the image.

Aqua has very well-defined guidelines for the size of its widgets. Swing, on the other hand, does not. The Aqua LAF tries to find a common ground. Since any combo box larger than twenty pixels would look out of place in Mac OS X, that is all that is displayed, even if the actual size of the combo box is bigger. The entire area that is active on other platforms is still active, but the button itself doesn’t appear as large. Note that some other components have similar sizing adjustments to align with the standards set in Apple Human Interface Guidelines.

To be consistent with Aqua button types and their defined use in Mac OS X, there are a some nuances of Swing buttons that you should be aware of:

• JButtons with images in them are rendered as bevel buttons by default.

• A default JButton that contains only text is usually rendered as a push button. (Over a certain height, it is rendered as a bevel button, since Aqua push buttons are limited in their height.)

• JButtons in a toolbar are rendered as bevel buttons with square, not rounded edges.

You can also explicitly set the type of button with JButton.buttontype which accepts toolbar, icon, or text.

 

AWT

By its nature, AWT is very different on every platform and there are a few high level things to keep in mind about AWT in Mac OS X.

The value of the accelerator key can be determined by calling Toolkit.getDefaultToolkit().getMenuShortcutKeyMask().

The default font encoding in Mac OS X is MacRoman. The default font encoding on some other platforms is ISO-Latin-1 or WinLatin-1. These are subsets of UTF-8 which means that files or filenames can be turned into UTF-8 by just turning a byte into a char. Programs that assume this behavior cause problems in Mac OS X. The simplest way to work around this problem is to specify a font encoding explicitly rather than assuming one.

If you do not specify a font encoding explicitly, recognize that:

• In the conversion from Unicode to MacRoman you may lose information.

• Filenames are not stored on disk in the default font encoding, but in UTF-8. Usually this isn’t a problem, since most files are handled in Java as java.io.Files, though it is good to be aware of.

• Although filenames are stored on disk as UTF-8, they are stored decomposed. This means certain characters, like e-acute (é) are store as two characters, “e”, followed by “´” (acute accent). The default HFS+ filesystem of Mac OS X enforces this behavior. SMB enforces composed Unicode characters. UFS and NFS do not specify whether filenames are stored composed or decomposed, so they can do either.

Mac OS X does not specify a default minimum size for windows. To avoid a 0 by 0 (0x0) pixel window being opened, the following default minimum sizes for Java windows are enforced:

• Borderless windows have a minimum size of 1 by 1 (1x1).

• Windows with a title bar have a minimum size of 128 by 32 (128x32).

In Java 1.4, java.awt.GraphicsDevice includes methods for controlling the full screen of a client computer through Java. In addition to these standard tools, Mac OS X provides a few system properties that may be useful for development of full-screen Java applications.

 

Accessibility

With some other platforms, the use of the Java Accessibility API requires the use of a native bridge. This is not necessary in Mac OS X. The code needed to bridge the Accessibility API to the native operating system is built in. Users can configure the accessibility features of Mac OS X through the Universal Access pane of System Preferences. If you are using the Accessibility API, your application can use devices that the user has configured there.

 

Sound

Java sound input is supported only at a frame rate of 44100 (in PCM encoding, mono or stereo, 8 or 16 bits per sample) by the Core Audio framework. If you need a different frame rate, you can easily resample in your application. By default, the Java sound engine in Mac OS X uses the midsize sound bank from http://java.sun.com/products/java-media/sound/soundbanks.html.

 

Input Methods

Mac OS X supports Java input methods. The utility application Input Method Hot Key, installed in /Applications/Utilities/Java/, allows you to configure a trigger for input methods. You can download sample input methods from http://java.sun.com/products/jfc/tsc/articles/InputMethod/inputmethod.html.

 

Java 2D

As with Java on other platforms, the Java2D API takes advantage of the native platform to provide behavior that is as close as possible to the behavior of a native application. In Mac OS X, the Java2D API is based on Apple’s Quartz graphics engine. This results in some general differences between Java in Mac OS X and on some other platforms. In Mac OS X, Java windows are double-buffered. The Java implementation itself attempts to flush the buffer to the screen often enough to have good drawing behavior without compromising performance. If for some reason you need to force window buffers to be flushed immediately, you may do so with Toolkit.sync. Normally Quartz displays text anti-aliased. Therefore by default, Java2D renders text in the Aqua LAF for Swing with KEY_ANTIALIASING set to VALUE_ANTIALIAS_ON. It can be turned off using the properties described in Java 1.4 System Properties, or by calling java.awt.Graphics.setRenderingHint within your Java application. Note that in applets, anti-aliasing is turned off by default. Since anti-aliasing is handled by Quartz, whether it is on or off does not noticeably affect the graphics performance of your Java code. Do not count on using XOR mode to repaint images. Whenever you are using anti-aliasing, as you often do by default in Mac OS X, repaint the graphics context if you need to replace text or an image.

 

Other system property-related issues

Java 1.3.1 on Mac OS X version 10.2 supported some user interface related system properties that are no longer supported in Java 1.4.1. This section highlights those properties as well as the new runtime system properties that are supported.

Unsupported System Properties

The following system properties were available in Java 1.3.1 but are no longer supported in Java 1.4.1. Some have similar replacements as noted.

com.apple.macos.use-file-dialog-packages
com.apple.macos.useScreenMenuBar

Use apple.laf.useScreenMenuBar.

com.apple.macos.useSmallTabs
com.apple.macosx.AntiAliasedTextOn

Use apple.awt.textantialiasing.

com.apple.mrj.application.growbox.intrudes

Use apple.awt.showGrowBox.

com.apple.mrj.application.live-resize

Supported System Properties

The following system properties are supported in Java 1.4.1 in Mac OS X version 10.2. Most of them accept a Boolean value. If they accept a different string that is noted. You can call them from the command line with the -D flag to java or in your code with System.setProperty. For example, you could set your Swing application to use the Mac OS X menu bar with either

java -Dapple.laf.useScreenMenuBar="true" yourApplication

or

System.setProperty("apple.laf.useScreenMenuBar", "true");

 

Core APIs

In general, the Core Java APIs behave as you would expect them to on other platforms so most of them are not discussed in this chapter. There are a couple of details concerning Preferences that you should be aware of.

The Preferences API is fully supported in Mac OS X, but there are two details you should be aware of to provide the best experience to users:

• The preferences files generated by the Preferences API are named com.apple.java.util.prefs. The user’s preferences file is stored in /Library/Preferences/ in their home directory (~/Library/Preferences/). The system preferences are stored in /Library/Preferences/.

• To be consistent with the Mac OS X user experience, your preferences should be available from the application menu. The com.apple.eawt.Application class provides a mechanism for doing this. See Java 1.4 API: Apple Extensions for more information.

Networking

Mac OS X version 10.3 supports IPv6. Because Java 1.4 uses IPv6 on platforms that support it, the default networking stack in Mac OS X is the IPv6 stack. You can make Java 1.4.2 use the IPv4 stack by setting the java.net.preferIPv4Stack system property to true.

 

JNI

JNI libraries are named with the library name used in the System.loadLibrary method of your Java code prefixed by lib and suffixed with .jnilib. For example, System.loadLibrary("hello") loads the library named libhello.jnilib.

If you are developing a Cocoa Java application, you need to load your JNI library using a different mechanism. If your library is called hello.jnilib, you should call System.load(NSBundle.mainBundle().pathForResource("hello", "jnilib", "Java")); Note that this assumes that your library is located in Resources/Java/.

In building your JNI libraries, you have two options. You can either build them as bundles or as dynamic shared libraries (sometimes called dylibs). If you are concerned about maintaining backward compatibility with Mac OS X version 10.0, you should build them as a bundle; otherwise you probably want to build them as a dylib. Dylibs have the added value of being able to be prebound, which speeds up the launch time of your application. They are also easier to build if you have multiple libraries to link together.

To build as a dynamic shared library, use the -dynamiclib flag. Since your .h file produced by javah includes jni.h, you need to make sure you include its source directory. Putting all of that together looks something like this:

cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers sourceFile.c

cc -dynamiclib -o libhello.jnilib sourceFile.o -framework JavaVM

To build a JNI library as a bundle use the -bundle flag:

cc -bundle -I/System/Library/Frameworks/JavaVM.framework/Headers -o libName.jnilib -framework JavaVM sourceFiles

For example, if the files hello.c and hola.c contain the implementations of the native methods to be built into a dynamic shared JNI library that will be called with System.loadLibrary(“hello”), you would build the resultant library, libhello.jnilib, with this code:

cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers hola.c

cc -c -I/System/Library/Frameworks/JavaVM.framework/Headers hello.c

cc -dynamiclib -o libhello.jnilib hola.o hello.o -framework JavaVM

Often JNI libraries have interdependencies. For example assume the following:

• libA.jnilib contains a function foo().

• libB.jnilib needs to link against libA.jnilib to make use of foo().

Such an interdependency is not a problem if you build your JNI libraries as dynamic shared libraries, but if you build them as bundles it does not work since symbols are private to a bundle. If you need to use bundles for backward compatibility, one solution is to put the common functions into a separate dynamic shared library and link that to the bundle.

A complete example of calling a dynamic shared library from a bundle, including both a makefile and an Xcode project, can be found at http://developer.apple.com/samplecode/JNISample/JNISample.html.

When building JNI libraries, you need to explicitly designate the path to the jni.h. This is in /System/Library/Frameworks/JavaVM.framework/Headers/, not /usr/include/ as on some other platforms.

Once you have built your JNI libraries, make sure to let Java know where they are. You can do this either by passing in the path with the -Djava.library.path option or by putting them in /Library/Java/Extensions/.

Native Applications That Invoke Java Through JNI

By default, if the first call into the JavaVM framework is JNI_CreateJavaVM where JNI_VERSION_1_2 is specified, the Java 1.3.1 virtual machine (VM) is used. This is done to maintain backward compatibility with the Java 1.3.1 version of applications that may already be in use on the system. If you need to use the 1.4.1 VM and link against the 1.4.1 version of jni.h, pass JNI_VERSION_1_4 instead of JNI_VERSION_1_2. If you call JNI_GetDefaultJavaVMInitArgs before JNI_CreateJavaVM you will also get Java 1.4.1.

More JNI-related docs:

How do I build and deploy JNI libraries on Mac OS X?

The JNISample sample code on our developer site demonstrates how to build a full JNI application with Xcode. The naming convention for JNI libraries is typically libXXX.jnilib, where XXX is the name of your JNI library as specified by your Java code’s System.loadLibrary call. dylibs placed in the Contents/Resources/Java subdirectory of an application bundle. or in one of the recommended extension directories (more information below). Any other locations will need to be specified using the java.library.path system property when starting your application, either using -D from the command line or within the Java->Properties subdictionary of a double-clickable app’s Info.plist file.

Apple Technical Q&A JAVA28: Creating JNI Libraries with Project Builder:

Q: How do I create a Mac OS X JNI (Java Native Interface) library with Project Builder?

A: Project builder does not have a template project, or a template target for JNI libraries. The following steps will create a Project Builder target for building a JNI library for Mac OS X.

1. Under the Project Menu, add a new target.

2. Select the target template called Library.

3. Set the target name to be lib{libname}.jnilib as in "libhello.jnilib".

4. Select the new target, and then a tab called Build Settings should appear in the pane next to the target's pane. Select the Build Settings target.

5. Scroll down to the Search paths panel.

6. Add the following path to the list of Headers (which is in the Search paths panel):

/System/Library/Frameworks/JavaVM.framework/Headers

7. Scroll down to the Expert Build Settings panel.

8. In the Expert Build Settings, delete the DYLIB_COMPATIBILITY_VERSION and the DYLIB_CURRENT_VERSION options. (The Delete key will delete them.)

9. In the Expert Build Settings, change the LIBRARY_STYLE option to BUNDLE. (Double click in the value column of a build setting to change it.)

10. Select the Files tab on the vertical pane to the left of the window.

11. Add the Java-generated header files and the native implementations to the target.

Note: JNI libraries must be in the path defined by the Java property "java.library.path" to be loaded with the System.loadLibrary("libname") method. To extend the java.library.path, define the environment variable DYLD_LIBRARY_PATH with the additional directories.

The default value of java.library.path in Mac OS X is:
.:/usr/lib:/usr/lib/java:/lib:/System/Library/
Framworks/JavaVM.framework/Versions/1.3/Libraries

Java applications built with Project Builder and MRJAppBuilder also search for libraries in the Contents/Resources/Java/ folder of the applications bundle.

Don't bother looking at Apple's Technote 1155 since it is for Mac OS 9 only.

Mac OS X JNI Revisited

* * *

Burried in Apple's documentation and one of the very best examples available for building JNI libraries on Mac OS X, is Apple's example of how to build a JNI-based application in Project Builder. You would normally never look at this sample for an example of how to build a JNI library because the focus of this example is on building an application, not a library. However, hiding in this sample is a demonstration of how to build a JNI library since this sample shows how to build an application that uses JNI. The best thing about this sample is that it generates both the Java application code, and the JNI library code, and then it builds both - and it shows you how to do it all in Project Builder (Xcode). Hence with this sample you not only have a demonstration of how to build a JNI app, but also a very clear and integrated example of how to build a JNI library that interfaces to a Java app. Hence, this sample is probably the best demonstration available on Apple's website of how to build a JNI library. But you might never think to look in this sample because it is both an application sample and it's hidden in the Project Builder for Java documentation.

 

Developing a JNI Application

When you need to leverage existing C or Objective-C code in a Java application or need to improve the performance of an application by executing critical parts natively instead of on the Java virtual machine, you use the Java Native Interface (JNI). The JNI provides a way for Java code to communicate with C-based libraries.

Project Builder provides a template that facilitates the development of JNI-based applications. For an explanation of the elements of that template, including its targets, see “The JNI Application Template”.

After creating a new JNI-based Application project from Project Builder's JNI Application template, Project Builder generates the source files for the native side and the Java side of the application.

Example Java & Native code for JNI application and external dylib:

Leveragejnilib.c source file in the Leverage project

#include "JNIWrapper.h"

int shared_function( const char *arg )

{

printf( "shared_function called with %s\n", arg );

return 42;

}

JNIEXPORT jint JNICALL Java_JNIWrapper_native_1method( JNIEnv *env, jobject this, jstring arg )

{

/* Convert to UTF8 */

const char *argutf = (*env)->GetStringUTFChars( env, arg, JNI_FALSE );

/* Call into external dylib function */

jint rc = shared_function( argutf );

/* Release created UTF8 string. */

(*env)->ReleaseStringUTFChars(env, arg, argutf);

return rc;

}

JNIWrapper.java source file in the Leverage project

import java.util.*;

public class JNIWrapper

{

static

{

// Ensure native JNI library is loaded.

System.loadLibrary("Leverage");

}

public JNIWrapper()

{

System.out.println( "JNIWrapper instance created" );

}

native int native_method( String arg );

public static void main ( String args[] )

{

System.out.println( "Started JNIWrapper" );

JNIWrapper newjni = new JNIWrapper();

int result = newjni.native_method( "Hello World !" );

System.out.println( "Finished JNIWrapper. Answer is " + result );

}

}

There is also a "JNISample" project from Apple at http://developer.apple.com/samplecode/JNISample/JNISample.html

 

* * *

The Java Virtual Machine

The foundation of any Java implementation is the Java Virtual Machine (VM). The Java 1.4.2 implementation for Mac OS X includes the Java HotSpot VM runtime and the Java HotSpot client VM from the Sun SDK 1.4.2_05 technology train. Mac OS X does not include a separate server VM. The -server runtime flag is available, but instead of invoking a server version of the VM, it invokes a VM that has been tuned for more server-oriented operation. The VM options available with the Java 1.4.2 VM in Mac OS X vary slightly from those available on other platforms. The available options are presented in Java 1.4 Virtual Machine Options.

Basic Properties of the Java 1.4.2 VM

You can use System.getProperties().list(System.out) to obtain a complete list of system properties.

JVM properties

java.version - 1.4.2

Mac OS X version 10.1 and earlier ship with earlier versions of Java. Use this property to test for the minimal version your application requires.

java.vm.version - 1.4.2_05

file.seperator - ‘/’

This is consistent with UNIX-based Java implementations, but different from Mac OS 9 and Windows.

os.name - Mac OS X

Make sure to check for Mac OS X, not just Mac OS because Mac OS returns true for Mac OS 9 (and earlier) which did not even have a Java 2 VM.

os.version - 10.3 or 10.4

Java 1.4 runs only in Mac OS X version 10.2 or later.

Note: The mrj.version system property is still exposed by the VM in Java 1.4.2. Although you may still use this to determine if you are running in the Mac OS, for forward compatibility consider using the os.name property to determine if you are running in the Mac OS since this property may go away in future attempts to further synchronize the Apple source with the source from Sun.

Mac OS X Java Shared Archive

To help increase the speed of application startup and to reduce the memory footprint of Java applications, the Java VM in Mac OS X makes use of a Java shared archive (JSA). The JSA contains the preprocessed internal HotSpot representations of common standard Java classes that would otherwise be found and processed from the standard classes.jar file. Since this data doesn’t change, it can be shared across processes by mapping the JSA file directly into shared memory. The JSA file is created upon first system boot after installation of Java. Since each Java application does not need to generate an independent archive at runtime, less memory and fewer CPU cycles are needed. There is nothing you need to do programatically to take advantage of these advances.

Generational Garbage Collection

Garbage collection (GC) is the means whereby the Java VM gets rid of objects that are no longer in use. Java provides an environment to the programmer where objects and the memory that they use are automatically reclaimed without programmer intervention. This runtime facility, GC, has been under development for decades. The basic ideas is that there is a set of root objects that reference other objects which in turn reference other objects and so on. If an object cannot be reached from one of these root objects, it is declared garbage and its memory space is reclaimed. Searching all objects has always been expensive. About twenty years ago the idea of generational garbage collection was introduced.

Generational GC takes advantage of the fact that most objects die young. That is, most objects are only in use for a short amount of time, a string buffer, for example. In generational GC, a section of memory is set aside where new objects are created. After this space is filled, the objects are copied to another section of memory. Each of these sections is referred to as a generation. The HotSpot VM keeps track of these objects so that it can find the connections back to the root objects when GC occurs.
When a GC is run, objects still in use may move up to a more tenured generation. Most generations have their own strategy for culling out objects no longer in use without having to search through all of the memory space. The oldest generation, however, has no such strategy.

One problem with this is that when garbage collection is run on the permanent generation it takes a while to go through all of that memory space. Moreover, over the course of time, multiple application instances will end up with many of the same objects in their respective permanent generation. If a user is running multiple Java applications, then the permanent generation of one often has the same resources as another which results in wasted memory.

More information on the Java HotSpot VM garbage collection is available online in Sun’s Technical White Paper, The Java HotSpot Virtual Machine, v1.4.1 available at http://java.sun.com/products/hotspot/docs/whitepaper/Java_Hotspot_v1.4.1/Java_HSpot_WP_v1.4.1_1002_1.html and in Tuning Garbage Collection with the 1.3.1 Java™ Virtual Machine available at http://java.sun.com/docs/hotspot/gc/index.html.

The Advantages of the Java Shared Archive

To get around the problem of wasted memory in the permanent generation, Apple implements a Java Shared Archive technology. This technology is similar to the concept of a shared library in C-based languages. Instead of each Java application needing to keep a separate copy of resources that usually end up in the permanent generation, they are able to share a single copy of these resources which adds a new immortal generation. There are some distinctions between this immortal generation and the other generations:

• Resources are explicitly placed there, they are not promoted to that generation.

• It is never garbage collected.

• A single immortal generation is shared by multiple applications.

When Mac OS X starts up, the Java VM starts in a special mode to build (or update) an archive of resources that would likely end up in the Permanent generation. After this archive file has been appropriately assembled, the VM shuts down until the user runs a Java application. When a user starts a Java application, the VM can bootstrap off of those resources already on disk, mapping them into the same memory space as the Java heap. Using the archive file speeds up application launch time.

Shorter launch time is a benefit for a single Java application running in Mac OS X. When multiple applications are running, a shared archive also uses less memory. Subsequent applications do not need to allocate space for the resources in the Java Shared Archive; the space has already been allocated on disk. They just need to map to it. The result is similar to a shared library. The permanent generation tends to be smaller since many of the objects that would be in the permanent generation are available in the Immortal generation.

Apple’s Java Shared Archive implementation in Mac OS X is fully compatible with the Java HotSpot specification and has been presented to Sun for further use within Java.

Note: The Java Shared Archive is used only if the default boot class is used. The use of java.endorsed.dirs or otherwise modifying the default boot class path prevents your application from using the Java Shared Archive.

In summary, the VM uses the generational heap to allocate internal data structures used to implement Java classes. These classes don’t change over time and don’t ever need to be garbage collected. The Mac OS X Java VM extends HotSpot’s notion of generations to include a new generation for these immortal objects. Along with memory savings, time is also conserved since this generation never needs to be searched for dead objects.

 

Native Platform Integration

The more your application fits in with the native environment, the less users have to learn unique behaviors for using your application. A great application looks and feels like an extension of the host platform.

J2SE’s cross-platform design demands a lot of flexibility in the user interface to accommodate multiple operating systems. The Aqua user interface, on the other hand, is streamlined to provide the absolute best user experience on just one platform.

The appearance and behavior of menu items varies across platforms. Unfortunately, many Java programmers write their applications with only one platform in mind. Having menus in the menu bar is highly encouraged, but it does not automatically provide the native experience of Mac OS X menus for two reasons:

• In Mac OS X an application’s menu bar is always visible when an application is the active application, whether or not any windows are currently open.

• The menu bar contains all of the menus that an application might use. If a menu has no functionality with the foremost window, the title for that menu is dimmed. Also, the titles of menus that have only menu items that apply to the content of windows are dimmed if no windows are open. Menus do not appear and disappear based on which window is foremost.

In short, the menu bar is always present and, except that some items may be dimmed at times, always looks the same. Removing the menus from your windows and putting them in the menu bar is a great first step that retains cross-platform compatibility.

Any Java application that uses AWT/Swing or is packaged in a double-clickable application bundle is automatically launched with an application menu similar to native applications in Mac OS X. This application menu, by default, contains the full name of the main class as the title. This name can be changed using the -Xdock:name command-line property, or it can be set in the information property list file for your application as the CFBundleName value. According to the Aqua guidelines, the name you specify for the application menu should be no longer than 16 characters.

The next step to customizing your application menu is to have your own handling code called when certain items in the application menu are chosen. Apple provides functionality for this in the com.apple.eawt package. The Application and ApplicationAdaptor classes provide a way to handle the Preferences, About, and Quit items.

Do not set menu item accelerators with an explicit javax.swing.KeyStroke specification. Modifier keys vary from platform to platform. Instead, use java.awt.Tookit.getMenuShortcutKeyMask to ask the system for the appropriate key rather than defining it yourself.

The default modifier key in Mac OS X is the Command key. There may be additional modifier keys like Shift, Option, or Control, but the Command key is the primary key that alerts an application that a command, not regular input follows. Note that not all platforms provide this consistency in user interface behavior. When assigning keyboard shortcuts to items for menu items, make sure that you are not overriding any of the keyboard commands Macintosh users are accustomed to.

Note: Since the ALT_MASK modifier evaluates to the Option key on the Macintosh, Control-Alt masks set for Windows become Command-Option masks if you use getMenuShortcutKeyMask in conjunction with ALT_MASK.

Like mnemonics, menu item icons are also available and functional via Swing in Mac OS X. They are not a standard part of the Aqua interface, although some applications do display them—most notably the Finder in the Go menu. You may want to consider applying these icons conditionally based on platform.

Contextual menus, which are called pop-up menus in Java, are fully supported. In Mac OS X, they are triggered by a Control-click or a right-click. Note that Control-click and right-click are a different type of MOUSE-EVENT, even through they have the same result. In Windows, the right mouse button is the standard trigger for contextual menus.

Here are some more Apple-specific properties one can use to help achieve better Java integration with Mac OS X.

com.apple.mrj.application.apple.menu.about.name

Sets the application name that is displayed in the application menu and in the Dock.

This property take a string of text as an argument. For example, java -Dcom.apple.mrj.application.apple.menu.about.name=”Application Name” yourApplication.

apple.laf.useScreenMenuBar

If you are using the Aqua look and feel, this puts Swing menus in the Mac OS X menu bar. Note that JMenuBars in JDialogs are not moved to the Mac OS X menu bar.

The default value is false. Java applications created with Project Builder have this set to true.

 

apple.awt.showGrowBox

Most native Mac OS X windows have a resize control in the bottom right corner. By default, Java application windows that use the Aqua look and feel have the functionality of this control, but there is no user interface cue that it is there. This flag causes the resize control to be displayed.

The default value is false.

 

apple.awt.brushMetalLook

This flag allows you to display your main windows with the “textured” Aqua window appearance. This should only be applied to the primary application window, and should not affect supporting windows like dialogs or preference windows.

The default value is false.

 

Rendering hints

apple.awt.antialiasing

Causes graphic primitives like line, arc, rectangle, and so on to be painted with antialiasing. By default text will also take this setting, though you can override that using apple.awt.textantialiasing. Even with this flag set to true from the command line, you may still set the KEY_ANTIALISING rendering hints for specific objects.

Although this is false by default, it is set to true when you use the Aqua look and feel. This makes the behavior more consistent with the native Mac OS X user interface. Note that even if you set this to false for an application that uses the Aqua look and feel, Aqua user interface elements themselves will still be drawn with antialiasing.

 

apple.awt.textantialiasing

Sets the KEY_TEXT_ANTIALIASING rendering hint. 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.

 

apple.awt.rendering

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

 

apple.awt.interpolation

Allows you to set the 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.

 

apple.awt.fractionalmetrics

Allows you to set the KEY_FRACTIONALMETRICS to use floating point font metrics instead of the default integer metrics. Options include VALUE_FRACTIONALMETRICS_ON andVALUE_FRACTIONALMETRICS_OFF.

 

Full screen Java

apple.awt.fakefullscreen

This flag causes full screen applications to be displayed in a window. It might be used during development of full screen Java applications.

The default value is false.

 

apple.awt.fullscreencapturealldisplays

When you have multiple displays, entering full screen mode normally darkens the secondary screen(s). Setting this to false overrides this default behavior and secondary screens are not darkened. This is useful for development purposes like debugging.

The default value is true.

 

apple.awt.fullscreenhidecursor

Hides the mouse cursor when in full screen mode.

The default value is true.

 

apple.awt.fullscreenusefade

If you change the screen resolution when entering full screen mode, the screen transitions by fading out of the old resolution and back in with the new resolution. If you do not change screen resolution, you normally do not see this fade effect. This setting enables that fade effect regardless of whether you have changed the screen resolution.

The default value is false

 

Window Positioning

apple.awt.window.position.forceSafeCreation

Enforces the creation of new windows on screen. New windows are not created outside of the Desktop where users would not be able to access them.

The default value is false.

 

apple.awt.window.position.forceSafeProgrammaticPositioning

Prohibits windows from being moved programatically into a position where users are unable to access them. The true setting promotes optimal interaction between the Java environment and the native window server. Setting this to false may result in unpredictable behavior in the windowing environment.

The default value is true.

 

apple.awt.window.position.forceSafeUserPositioning

Prohibits users from moving windows into a position where they would no longer be able to access them.

The default value is false.

 

System Properties

The Mac OS X–specific system properties let you easily add native behavior to your Java applications with a minimum of work on your part. A complete list of supported Mac OS X system properties, including how to use them, is available in Java 1.4 System Properties.

Specific Changes From Java 1.3.1 to 1.4.1

The restructuring of the Java implementation has resulted in many changes that are not directly visible to you as a developer. However, there are a few key areas to be aware of:

• This release of Java is installed in addition to the Java 1.3.1 release of Java already included with Mac OS X version 10.2. For the first time, Mac OS X supports two different Java environments, Java 1.3.1 and Java 1.4.1. This change may affect your Java applications deployed on the Mac OS X platform. Chapter 3, “Multiple Versions of Java”, discusses this issue in more detail.

• With the change from 1.3.1 to 1.4.1 and the underlying architectural changes, the runtime system properties available to you have changed also. These changes are outlined in detail in Chapter 4, “Runtime System Properties”,.

• For Java 1.3.1, AWT and Swing were implemented through the Mac OS X Carbon API. In Java 1.4.1 these implementations have made the transition to the Cocoa API. This change brings a true multithreaded environment and enhancements to the Aqua look and feel. As a Java developer, you don’t need to do anything different to take advantage of these benefits. If though, you rely on native code for any aspects of your Java applications, the change from Carbon to Cocoa will probably affect how you access native code and what native code is most readily available to you. Java 1.4.1 Development for Mac OS X provides more details on this topic.

• Browser-based applet support has been improved to provide much smoother and more reliable performance. This includes Java 1.4.1 support from Apple’s Safari browser.

• Native support for the Java Accessibility API is provided by default in AWT. There is no need for you to provide a bridge to native code to make your applications accessible. Users of assistive technologies that have configured the Universal Access system preferences will automatically be able to use your Java application with those technologies. Swing Accessibility is not fully implemented.

• Native support for the security features is provided through the Mac OS X Secure Transport API. This allows users to manage certificates through their Keychain and the Keychain Access application.

• AppleScript support is available for Java applications through two mechanisms. Basic Apple Events are supported through implementing the handlers in com.apple.eawt.ApplicationListener. Additional user interface scripting can be done by using the AppleScript UI Element Scripting plug-in available with the December 2002 Mac OS X Developer Tools.

• Jar Bundler, a new application for bundling Java applications as Mac OS X applications, is included. It replaces MRJAppBuilder, which is no longer supported.

• Two versions of the Java Plugin Settings application are now provided. These are installed in /Applications/Utilities/Java. One version allows you to access settings for the Java Plug-in 1.3.1 used by Internet Explorer and most other browsers. The other allows you to access settings for the Java 1.4.1 Plug-in used by Safari.

• In Java 1.3.1 in Mac OS X, the ICC_ColorSpace implementation is based on Apple's ColorSync technology. In Java 1.4.1, this is replaced with Sun's implementation. This change fixes compatibility issues when dealing with color profiles in Java on other platforms.

• The com.apple.mrj packages have been deprecated. New classes that provide some of the same functionality have been included in the com.apple.eio and com.apple.eawt packages. These are documented in the Java 1.4.1 API Reference: Apple Extensions.

• With Java 1.3.1, you could explicitly specify Java 2D graphics hardware acceleration. With Java 1.4.1, hardware acceleration is handled by the Mac OS X Quartz Extreme graphics engine with no need for developer intervention.

• JDirect is not supported in Java 1.4.1. However, it still works as a part of Java 1.3.1.

• QuickTime for Java is not supported in Java 1.4.1. However, it still works as a part of Java 1.3.1.

As a developer, there are many ways you can determine whether Java 1.4.1 is installed, System.getProperty(“java.vm.version”) and java -version probably being the simplest. A user shouldn’t have to resort to the command line. Instead they can just use the Finder to look in /Library/Receipts for an item named Java1.4.1.pkg.

 

Introduction to Project Builder for Java

Project Builder was the forerunner to Apple's current development environment, Xcode. Although most of the documentation related to building Java on OS X refers to Project Builder, most of it applies equally to Xcode as well.

Project Builder templates are prebuilt projects that give you a head start in the development of an application. Figure 1-1 shows the New Project pane of the Project Builder Assistant, listing the Java project templates you can use to develop applications. When you want to develop a Swing-based application, for example, you can start with the Swing application template, which provides a fully configured application that follows Apple’s guidelines for GUI (graphical user interface) applications. That template is also useful if you’re new to Java and Swing and want to see the inner workings of a working application.

The types of Java applications you can develop with Project Builder and their corresponding project templates:

Application type Template name
Text-based application
Java Tool
Swing applet Java Swing Applet
Swing application Java Swing Application
JNI (Java Native Interface) application Java JNI Application
AWT (Abstract Window Toolkit) applet
Java AWT Applet
AWT application Java AWT Application

Project Builder has a powerful and flexible build system that facilitates the potentially complex tasks involved in building and deploying products, which include applications, libraries, frameworks, JAR files, and so on. The main elements involved in building products are targets. A project can contain more than one product, each produced by a target. In the case of text-based application projects, such as Java tool projects, the target is a JAR file created by the project’s only target.

In general, a target encompasses instructions on how to build a product, which can be an application or a component of one. Build settings are properties that tell Project Builder how to build a product. Build phases are concrete steps Project Builder takes to build a target; for example, compiling source files into object files and linking object files to create an executable file.

 

The Tool Template

The Java Tool template provides the files needed to create a simple, text-based application. It includes source files for the class with the main method, the JAR manifest, and the man page.

The following list describes the files of a Java tool project named Hammer:

1.Hammer.java: Java source file that contains the main method. Project Builder names this file after the project.

2.Manifest: File that contains information that Project Builder adds to the MANIFEST.MF file of the generated JAR file.

3.Hammer.1: Source for the man page that documents the tool.

4.Hammer.jar: JAR file in which Java class files, the manifest file, and other resources are stored for distribution. This is the product of the project. It’s red because it hasn’t been produced yet, so the file doesn’t exist in the file system.

The items under Build Phases in the target editor list the build phases of the Hammer target. The phases are executed from top to bottom when the product is built. That is, the build phases are executed in the following order:

1.Sources Determines which Java source files are to be compiled (run through the javac compiler).

2.Java Resource Files Indicates which files to copy to the root level of the product (the top level of the JAR file).

3.Frameworks & Libraries Lists frameworks or libraries to which the Java class files generated in step 1 must link against.

4.Copy Files Copies files to specific parts of a product (for example, its resources directory or its plug-ins directory).

The Swing Application Template

The Java Swing Application template provides the files needed to create a desktop application. It includes source files for a controller class (which includes the main method) and two JFrames that the user can make visible through menu commands, an icon file, and a properties file. Figure 1-4 shows the files that make up a Java Swing application project.

The following list describes the files in a Java Swing application project named Dance and their relationship to the actual application:

1.Dance.java, AboutBox.java and Preferences.java: Java source files that implement an About box and a preferences dialog.

2.Dance.icns: Icon file that contains the icon that the Finder displays for the application package.

3.Dancestrings.properties: File that contains the names and values of application properties accessible at runtime. Project Builder places this file inside the JAR file for the application.

4.Dance.app: Application package that contains Mac OS X–specific information for the application, as well as the application’s JAR file.

 

The JNI Application Template

The Java Native Interface (JNI) provides a standard interface for communication with native libraries. You may want to use the JNI if you need to interface with native, legacy code from Java applications or when you want to improve the performance of an application by porting certain tasks to native code.

Project Builder provides a template with which you can develop projects that include both native code and Java code.

The most interesting part of the Pronto project are its targets. While the previous project types, tool and Swing application, required only one target, a JNI project requires several targets. This is because a JNI project contains three products, a JNI library (which contains the compiled C code), a header to the library, and a JAR file for the Java side of the application.

The project has three main targets:

• JNIWrapper Compiles the Java source files of the application and archives them in a JAR file. This is the Java application.

• CreateHeaders Creates C function prototypes from Java class files in the JAR file generated by the JNIWrapper target.

• JNILib Builds the native library by compiling Prontojnilib.c and linking it with the Java VM framework (/System/Library/Frameworks/JavaVM.framework).

The Native target is an aggregate target. Its purpose is to enclose the JNIWrapper, CreateHeaders, and JNILib targets into one build unit, so that any action performed on it is performed on all the targets it contains. The BuildUsingMake target bypasses the Project Builder build system. It uses gnumake (/usr/bin/gnumake) to build the application.

You can find detailed information on the JNI at http://java.sun.com/j2se/1.4/docs/guide/jni/.

 

Build System

Project Builder uses the Jam software build tool as its build engine. Jam allows Project Builder to easily manage dependencies between a project’s elements. It can also take advantage of computers with two or more central processing units (CPUs).

 

Build Settings

Build settings are similar to Java properties: They store values that Project Builder uses to build products.

Project Builder facilitates configuring some build settings through specialized panes. However, you can set the value of any build setting directly through expert panes. Expert panes show the configuration build settings as a list of key-value pairs. Through these panes you can set the values of build settings for which the more user-friendly specialized panes do not provide a user interface.

The first table below lists build settings that identify a project and tell Project Builder where to put temporary files generated during product building.

Project Build Settings

Build setting Description
PROJECT_NAME
Name of the project. For example, MyProject. You should not modify this setting directly.
SYMROOT Base location for built products. For example, MyProject/build.
BUILD_DIR Base location for the temporary files generated by a project’s targets. For example, MyProject/build. You should not modify this setting directly.
TARGET_BUILD_DIR Base location for built products. It’s set to $BUILD_DIR in development builds (for example, MyProject/build), $INSTALL_DIR (for example, /tmp/MyProject.dst/usr/bin) in deployment builds when the product is installed, and $BUILD_DIR/UninstalledProducts when the product is not installed.

Build settings that determine where files are placed when you use pbxbuild to install a product.

Build setting Description
DSTROOT
Base location for the installed product. For example, /tmp/MyProject.dst/
INSTALL_PATH Location of the installed product. For example usr/bin.
INSTALL_DIR Fully qualified path for the installed product. By default, it concatenates DSTROOT and INSTALL_PATH. So, with the example values, it evaluates to /tmp/MyProject.dst/usr/bin. You should not modify this setting directly.

 

The following table lists build settings that identify a target and tell Project Builder where to put the files it generates.

Build setting Description
TARGET_NAME
Name of the target. For example, MyProject. You should not modify this setting directly.
ACTION The action being performed on a target. Its possible values are build, clean, or install (through pbxbuild). You should not modify this setting directly.
TEMP_DIR Location for a target’s temporary files. For example, MyProject/build/MyProject.build/MyTarget.build.

 

The following table lists build settings used to call javac or jikes to compile Java source files.

Build setting Description
CLASS_FILE_DIR
Base location for Java class files. For example, MyProject/build/MyProject.build/MyTarget.build/JavaClasses.
JAVA_COMPILER_TARGET_VM_VERSION Defines the Java virtual machine version that javac compiles Java source files to—for example, 1.4. By default, this setting is undefined.

 

The following table lists the build setting that defines the archive of Java class files and the creation of the application package.

Build setting Description
JAVA_MANIFEST_FILE
Path (relative to the project’s root directory) to a manifest file to use when archiving Java class files into a JAR file. For example, Manifest.

 

Targets

Project Builder targets represent a product, such as an application or a framework. A project can produce more than one product. For example, a project can contain Java source files, which are compiled into Java class files by javac, and Objective-C source files, which are compiled into object files by gcc. Such a project must contain at least two targets, one that compiles the Java sources files and another that compiles the Objective-C source files. The build settings introduced in “Build Settings” are what Project Builder uses to determine how to build a product.

Each target has its own set of build setting values; they are autonomous entities within a project. However, you can tell Project Builder that a target depends on one or more additional targets. That way you can guarantee, for example, that when target A needs files produced by target B, target B is executed before target A. In addition, if there’s a problem with target B, target A doesn’t get executed.

In addition, Project Builder provides the ability to add aggregate targets to a project. An aggregate target contains no product-building instructions; instead, it groups other targets. The operations you perform on aggregate targets are carried out on all the targets they enclose.
Each target can contain some or all of the following types of elements:

Build settings - The group of build settings that control the build system.

Information property list entries -Application package–specific information, such as type, version, icon, and so on.

Build phases - Types of tasks to perform on a set of a project’s files, such as compile, link, archive, copy, and so on.

 

Target Information Panes

Target information panes group information about how a product is built. They contain a user-friendly view of the values of certain build settings. These information panes are grouped in three major groups: Summary, Settings and Info.plist Entries.

 

Target Summary

The Summary pane shows summary information for a project, including its name, type, and developer comments.

The following table describes the elements of the Target Summary pane.

Element label Description Corresponding build setting
Product type
Indicates the type of project. Can be Application, Tool, Framework, and so on.
None.
Base product name Name of the generated product file without an extension. PRODUCT_NAME
Comments Developer comments about the target. None.

 

Build Settings Pane

The Build Settings pane groups views of the build settings of a project. It includes two views: Simple View and Expert View. The Simple View provides a easy-to-use user interface to various build settings. The Expert View lists all the build settings. You can use this view when the other views don’t provide a way of configuring a particular build setting.

General Settings

The General Settings pane shows information that pertains to the entire project.

Search Paths

The Search Paths pane determines the places Project Builder searches for frameworks, libraries, Java classes, and headers (in the case of a JNI application) to build the selected target.

Element label Description Corresponding build setting
Headers
Search paths for Objective-C header files. HEADER_SEARCH_PATHS
Frameworks Search paths for frameworks. FRAMEWORK_SEARCH_PATHS
Libraries
Search paths for libraries. LIBRARY_SEARCH_PATH
Java Classes Search paths for Java class files or JAR files. JAVA_CLASS_SEARCH_PATHS

 

Java Compiler Settings

The Java Compiler Settings pane determines some compiler settings for the selected target.

Element label Description Corresponding build setting
Java Compiler
Determines the compiler to use to compile Java source files. The options are javac and jikes JAVA_COMPILER
Disable warnings
When selected, the compiler doesn’t produce warnings. JAVA_COMPILER_DISABLE_WARNINGS
Show usage of deprecated API
When selected, the compiler warns about deprecated API use. JAVA_COMPILER_DEPRECATED_WARNINGS
Generate debugging symbols When selected, the compiler generates debugging symbols. JAVA_COMPILER_DEBUGGING_SYMBOLS
Target VM version The virtual machine version the compiler is to produce Java class files for. JAVA_COMPILER_TARGET_VM_VERSION
Source file encoding Specifies the character encoding used in all the Java source files that are to be compiled. JAVAC_SOURCE_FILE_ENCODING
Other Java Compiler Flags Additional compiler options.
JAVA_COMPILER_FLAGS

 

Java Archive Settings

The Java Archive Settings pane determines how Java class files in the selected target are archived.

Element label Description Corresponding build setting
Product type
Determines whether Java class files are archived in a JAR file. JAVA_ARCHIVE_CLASSES
Compress
When unselected, the Java class files are stored in the JAR file, but are not compressed. JAVA_ARCHIVE_COMPRESSION
Archive file extension The extension to use for the JAR file. The options are .jar, .war, and .ear. CLASS_ARCHIVE_SUFFIX
Manifest file Name of the supplemental manifest file. JAVA_MANIFEST_FILE

 

Pure Java–Specific

The Pure Java Specific pane contains settings that are specific to Pure Java.

Element label Description Corresponding build setting
Main Class
Fully qualified name of an application’s main class. Java/MainClass
Class Path
List of paths to Java class files of JAR files the application uses. Java/ClassPath/
Place JFrame menu bars at top of screen When selected, the application’s menu bar follows Mac OS X style: It’s placed at the top of the screen instead of within each application window. Java/Properties/com.apple.macos.useScreenMenuBar
Growbox intrudes When selected, the resize control is part of the window pane. When unselected, a white band is added to the bottom of the window, so that the resize control doesn’t intrude in the windows’ content. Java/Properties/com.apple.mrj.application.growbox.intrudes
Set cwd to Contents/Resources/Java subdirectory When selected, the application’s working directory is set to the bundle’s Contents/Resources/Java directory. Java/WorkingDirectory
Anti-alias text Toggles text anti-aliasing. Java/Properties/com.apple.macosx.AntiAliasedTextOn
Live resizing Toggles live resizing of windows.
Java/Properties/com.apple.mrj.application.live-resize
Target VM Version Version of the Java runtime the application requires. For example, 1.4+. Java/JVMVersion
Additional VM Options Command-line options to add to the java invocation. For example, -Xfuture -Xprof. Java/VMOptions
Additional Properties
Additional Java system properties, which you can access through System.getProperty. Java/Properties/

 

Known Issues

The issues discussed here are known issues with the Mac OS X implementation of Java 1.4.1. These issues may or may not be resolved in a future release of Java for Mac OS X. Information on tracking these bugs is available in “Filing and Tracking Bugs”. Additional bug reports on these issues are welcome.

Each issue is broken down as follows:

• A Radar number that Apple uses to track the issue is followed by a brief statement of the issue.

• The Description field provides more details about the issue.

• The Workaround field may give you additional information about how you can work around that particular issue in your code. If it says, “None,” there is at the moment no currently a suggested workaround for that particular problem.

 

Java Aqua LAF
Radar #3156528
JFrames are not garbage collected when using the screen menu bar.
Description:
If the screen menu bar is enabled via com.apple.laf.useScreenMenuBar, JFrames with menu bars set with setJMenuBar may not be garbage collected. If many such frames are created and then closed, this may result in an OutOfMemoryError.
Workaround:
Explicitly remove the JMenuBar when disposing of the frame.
Radar #3166127
JOptionPane dialog buttons have mnemonics.
Description:
JOptionPane.showConfirmDialog displays Yes and No with an underscore under the Y and the N. These underscores should not be visible with the Aqua look and feel.
Workaround:
None.
Radar #3167784
JTextArea.setCaretPosition does not place caret correctly.
Description:
After appending text to a JTextArea and then calling setCaretPosition to set the caret at the end of the appended text, the caret is not always placed at the end of the text.
Workaround:
None.

 

Java AWT
Radar #3134617
Modal dialogs don't render parent windows inactive.
Description:
With Java 1.3.1 in Mac OS X, a user could not minimize a Java Frame that was behind a modal Java window. In Java 1.4.1, this is possible. This difference arises due to the use of Cocoa for Java windows and is being analyzed as to whether it should be considered a bug.
Workaround:
None.

 

Java Events
Radar #3164718
Control-drag generates mouseMoved, not mouseDragged.
Description:
Moving the cursor with the Control key and the mouse key held down generates mouseMoved events. This should generate mouseDragged events.
Workaround:
None.

 

Java Graphics
Radar #3160445
Apparent random crashes of Java applications.
Description:
Some applications that use Java2D can crash unexpectedly with a crash log that specifies a failure in Java_apple_awt_CRenderer. This is a known issue and is being investigated.
Workaround:
None.
Radar #3160678
GradientPaint not working for custom buttons.
Description:
One way to achieve a translucency effect in a component is to use gradient paint with alpha. This does not work in this release. A solid color may be displayed instead.
Workaround:
None.
Radar #3163400
Crash in mutlithreaded draw.
Description:
Multithreaded drawing windows with AWT buttons may result in a crash.
Workaround:
None.
Radar #3174367
Poor graphics performance with some image types.
Description:
32-bit RGB images with alpha can have the alpha channel pre multiplied or not. If your Java2D application makes use of ARGB images where the alpha channel has not been premultiplied, you might notice poor graphics performance in Mac OS X. This is especially evident where the ARGB image is being drawn into as a graphics context.
Workaround:
When constructing ARGB images, designate the image type as ARGB_PRE instead of ARGB.

 

Java HotSpot
Radar #3129210
The -Xincgc VM flag does not work.
Description:
The train garbage collector is not implemented in Java 1.4.1 so the -Xincgc does not have any effect on your code.
Workaround:
None.

 

Java Printing
Radar #3183076
Java Print Service API does not work.
Description:
The Java Print Service API available in the javax.print.* packages is not functional. This should not be confused with the standard Java 2 printing API available in java.awt.print which is fully functional.
Workaround:
None.

 

Java Security
Radar #3173133
Java Kerberos does not work well with the default Mac OS X Kerberos implementation.
Description:
There are known issues with the interaction of Java and the operating system when dealing with Kerberos authentication. The Java environment is unable to correctly locate the credentials cache or tickets on the system.
Workaround:
None.

 

Java Sun Plugin
Radar #2903948
httpsessions are not maintained for Applets.
Description:
Applets that make multiple HTTP URLConnections initiate a new httpsession with the server every time. If cookies are used to determine connections, note that cookie data is not neccesarily shared between the browser and the Java Plug-in. This is at the discretion of the browser vender.
Workaround:
Do not make session information dependent on cookies.

 

Java Swing
Radar #2884768
JMenu.getLocationOnScreen reports incorrect value for screen menu bar.
Description:
When the menu bar is set to be at the top of the screen with apple.laf.useScreenMenuBar, getLocationOnScreen returns the location of JMenu components as if they were not in the menu bar.
Workaround:
None.
Radar #3168263
javax.swing.JFileChooser.rescanCurrentDirectory doesn't update the file listing.
Description:
If you move files into or out of a directory, javax.swing.JFileChooser.rescanCurrentDirectory does not reflect these changes as it should.
Workaround:
None.
Radar #3172089
Resizable windows have no indicator of a resize area.
Description:
By default, Java applications do not have the resize control in the bottom right corner that native Mac OS X applications have. Since many Java developers are not accustomed to having this resize control present when they design their user interface, the decision has been made to not include it by default.
Workaround:
If you do want the resize indicator in your windows, add the apple.awt.showGrowBox system property. Set it to true either at the command line, with the -D flag to java, or in your code with System.setProperty.

 

Java Text
Radar #2826318
Double-byte characters are not displayed correctly if the language preference is not set.
Description:
Using logical fonts for screen font or in an editing window, double-byte characters don’t display correctly in the default Roman script system.
Workaround:
Change the script behavior setting in the Language pane of the International System Preferences.
Radar #3121780
Many of the fonts available in Mac OS X appear to be broken.
Description:
If you are constructing new fonts based on the value returned from aFont.getFontName, where aFont is one of the fonts returned from GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(), not all of the system fonts in Mac OS X are valid fonts for use in Java.
Workaround:
Use Font.getName instead of Font.getFontName.

 

Java Tools
Radar #2962223
Jar Bundler cannot open existing application bundles.
Description:
Jar Bundler is useful for building new application bundles from JAR files or class files. It does not have functionality included for modifying existing application bundles.
Workaround:
None, although you can modify the Info.plist settings of an application bundle in any text editor. Most of the Jar Bundler settings are stored in the Info.plist.
Radar #3166010
Project Builder uses gdb for Java debugging.
Description:
By default, Project Builder uses gdb instead of jdb for Java debugging.
Workaround:
In the Target pane select your executable in the Executables list. You should now see a pane that lets you modify the characteristics of that executable. In the Launch Configuration settings change "Configure" to "Debug action." Change "Launch using" to "Java Debugger".

 

Java Web Start
Radar #2905825
Java Web Start applications may hang for network home directories.
Description:
If a home directory is on an NFS mounted volume, Java Web Start applications hang shortly after they have been launched.
Workaround:
Use either a local account or change the network home directory to a AFP.

 

Other notes

Using Java Studio Creator on Mac OS X

Thanks to its highly optimized and fully standard Java implementation, Mac OS X is known as an excellent platform for developing and deploying Java applications. The recently released Sun Java Studio Creator for Mac OS X—a visual IDE for developing Web applications—only strengthens the case.

 

jsvc

There is a jsvc daemon for Tomcat that acts as a Java server but it doesn't really seem to help or alleviate the security issues on OS X - plus it is not installed on OS X by default.

http://jakarta.apache.org/commons/daemon/jsvc.html

sudo

sudo threads from Apple mailing list

sudo that voodoo that you do so well

 

Links

http://www.onjava.com/pub/a/onjava/2003/10/08/macosxjava.html