ADC Home > Documentation > Release Notes
Mac OS X 10.0 Release Notes:
|
Name |
Value |
Comments |
|
|
This value was "Darwin" in early
pre-releases of Mac OS X, and "Mac OS" in earlier versions
of MRJ. It is suggested that you use
|
|
|
This was "1.1" (the version number of the Darwin kernel) in early pre-releases of Mac OS X. |
|
|
Testing for the existence of this property is the general way to detect whether you are using an Apple-developed JVM, although to detect specific features like JDirect or MRJToolkit it is better to use reflection to check for the existence of the specific classes they use. |
|
|
This differs from previous versions of MRJ, which used '\r', but is consistent with Unix-based Java implementations and with the BSD and Cocoa frameworks. |
Java on Mac OS X sets a default locale based on the choice in System Preferences -> International: French maps to fr_FR, English to en_US, Japanese to ja_JP, French Canadian to fr_CA, etc.
In order to get a locale and language combination not supported by System Preferences, such as French language in the U.S. (fr_US), the default locale can be overridden by the following settings before the Java VM starts up. The options listed first override the later ones.
user.language
and
user.region
, defined on the java
command
line, or in MRJAppBuilder property settings.LC_ALL
environment variable, set
to one of the ISO standard language (optionally plus region)
codes. LC_ALL
is mapped to locale using a set of
default rules derived from the language codes outlined in ISO 639
and the country codes outlined in ISO 3166, such as en ->
en_US, fr -> fr_FR, ja -> ja_JP, etc. See www.unicode.org
for more details on these ISO specifications.LANG
environment variableSpecifying a locale within Java code using
Locale.setDefault(
newLocale
)
can be done after the VM is running, and overrides all other
options.
Java debugging is now fully operational in Project Builder, and is the recommended way to debug your Java applications. See the Project Builder documentation for more details.
jdb, the command-line Java debugger, works with the HotSpot Java Virtual Machine. To debug your code with jdb, do:
$
jdb
nameofjavaclass
arguments
See the jdb
man page for more details.
Currently, "/usr/bin/java" is a script. Because gdb won't recognize the script as an executable format, you can't simply type "gdb java" to debug your native code. To debug using gdb, you must type the full path to the java executable, like this:
$
gdb /System/Library/Frameworks/JavaVM.framework/Versions/1.3/Commands/java
In the future, "/usr/bin/java" will be restored to a symbolic link.
Once gdb starts, you may establish a different CLASSPATH for loading java code from within gdb:
(gdb)
setenv CLASSPATH
foo
:
bar
(gdb)
run
nameofjavaclass
arguments
The VM exports two useful functions for use inside gdb. The
ps
function prints the Java stack of the current thread,
and the pss
function prints the stacks of all Java
threads:
(gdb) call (void)ps()
(gdb) call (void)pss()
Here is sample output from pss()
:
"Thread-1" prio=5 tid=0xbb810 nid=0x13d3510 waiting on monitor [0x1777000..0x1777b68]
at java.lang.Object.wait(Native Method)
- waiting on <222d1260> (a sun.misc.TimerTickThread)
at java.lang.Object.wait(Object.java:420) at sun.misc.TimerTickThread.returnToPool(Timer.java:608) at sun.misc.TimerTickThread.run(Timer.java:630) "TimerThread" prio=5 tid=0xb9020 nid=0x13d2ca0 runnable [0x16c8000..0x16c8b68] at java.lang.Object.wait(Native Method) - waiting on <222d1220> (a sun.misc.TimerThread) at sun.misc.TimerThread.run(Timer.java:371) - locked <222d1220> (a sun.misc.TimerThread) "SunToolkit.PostEventQueue-0" prio=6 tid=0xb8380 nid=0x13af970 waiting on monitor [0x15d7000..0x15d7b68] at java.lang.Object.wait(Native Method) - waiting on <222d2f00> (a sun.awt.PostEventQueue) at java.lang.Object.wait(Object.java:420) at sun.awt.PostEventQueue.run(SunToolkit.java) - locked <222d2f00> (a sun.awt.PostEventQueue) "AWT-EventQueue-0" prio=6 tid=0xb7900 nid=0x13af710 waiting on monitor [0x1556000..0x1556b68] at java.lang.Object.wait(Native Method) - waiting on <222d3258> (a java.awt.EventQueue) at java.lang.Object.wait(Object.java:420) at java.awt.EventQueue.getNextEvent(EventQueue.java) - locked <222d3258> (a java.awt.EventQueue) at java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java) at java.awt.EventDispatchThread.run(EventDispatchThread.java)
Note that the stack traces above show monitor status. There are
several ways to enable this option (this applies also to all other
-XX:
based VM options):
-XX:+JavaMonitorsInStackTrace
on the java
command line..hotspotrc
file in your home directory.
This file gets parsed every time a Java VM starts up, so
this gives you a way to set options even for double-clickable
binaries or when embedding within another application. Include a
line containing: +JavaMonitorsInStackTrace
in your
.hotspotrc
file.To print the current stacks without having to run inside gdb:
ps
command line tool, then deliver a
SIGQUIT to that process. Here is the command sequence:
$
ps -auxwww | grep "Applet Launcher"
user 557 0.2 6.2 211952 16236 ?? S 0:06.47 /Applications/.../Applet Launcher -psn_0_1703937
user 559 0.0 0.1 5724 188 std UV+ 0:00.00 grep AppletLauncher$
kill -QUIT 557
Please note that if you deliver a signal to a process that is
running in gdb, gdb will break on the signal. You can just continue
on (with the command "c
") as you are actually not
interested in the signal itself, but in the output the signal handler
gives you.
If you are reporting a bug that results in a crash or a deadlock,
please reproduce the bug while running in gdb, call pss(),
and include the thread dump in the bug report. In case of a crash,
also include the native stack trace printed by the
bt
command. To get all native backtraces, use
the gdb command "thread apply all bt
".
See the gdb
man page for more details.
Java on Mac OS X provides hprof as a basic profiling tool. While the CPU timing it provides is useful, the monitor output is unreliable and we do not recommend its usage for contention analysis. This will be improved in a later release.
The HotSpot Java VM includes the -Xprof
option which
provides basic flat CPU usage on a pre-thread basis, which we have
found useful internally.
In Mac OS X, native methods that are implemented using the Java Native Interface are built into JNI libraries. Only the application that dynamically loads a JNI library has access to it. JNI libraries must be mach-o. CFM libraries are not supported. See TechNote 2003: Moving Your Code to Mac OS X, and the Mac OS X System Overview book for more details on mach-o and CFM.
JNI libraries are always named
lib
name
.jnilib
, where
name
is the value of the string used in the call
to System.loadLibrary()
. For example, to load the
library named libhello.jnilib
, you would make the
following call in your Java code:
System.loadLibrary("hello");
To build a JNI library, execute the following command:
$
cc -bundle -I/System/Library/Frameworks/JavaVM.framework/Headers -o lib
name
.jnilib -framework JavaVM
sourceFiles
For example, if the files hello.c
and
goodbye.c
contain the implementations of the native
methods to be built into libhello.jnilib
, you would
build libhello.jnilib
with the following command:
$
cc -bundle -I/System/Library/Frameworks/JavaVM.framework/Headers -o libhello.jnilib -framework JavaVM hello.c goodbye.c
To build a C application that starts a Java VM sesssion, you must link with the JavaVM framwork. e.g.
$
cc myapp.c -I/System/Library/Frameworks/JavaVM.framework/Headers -framework JavaVM -o myapp
The AWT implementation is a Carbonized version of the one in MRJ 2.2.4, extended to support Java2.
Window resizing is "live" by default. To disable this behavior, see the section on GUI customization.
Window titles, controls, menu titles and menu items can now use any Unicode characters supported by Mac OS X. (In previous versions of MRJ, characters of different non-Roman writing systems, e.g. Kanji and Arabic, couldn't be mixed in a single title.)
Window coordinates and insets are now compatible with the JDK. In
a nutshell: Window bounds refer to the outside of the window's
frame, and the coordinates of the window put (0,0) at the top left of
the title bar (not at the top left of the content region as in
earlier MRJs.) The getInsets
method returns the amount
by which content needs to be inset in the Window to avoid the window
border. This should only affect applications that are doing precision
positioning of windows (especially full-screen windows), or those
that bypass LayoutManagers to do their own hardcoded component
positioning.
Windows in Mac OS X are double-buffered. Java on Mac OS X 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, just call Toolkit.sync().
Java processes that are launched from a shell will not show up in the Dock or the floating Application List until/unless they show a window. In the Dock, these processes will then show up as items with a generic document icon, even though they're applications (currently, if more than one java process is launched from the command line, only one icon shows up in the Dock). This allows server-type processes to run behind the scenes with no user visible manifestation. In contrast, any app built with MRJAppBuilder will always be user visible, and have the icon you have selected for it.
Our Graphics/Java2D implementation is based on Apple's Quartz graphics engine. Java2D and Quartz have very similar feature sets, inherited largely from PostScript. Java on Mac OS X uses Quartz for all graphics -- as opposed to the JDK, which drops down to GDI or X-Windows for simple 1.1-style drawing -- and while Quartz is very fast at complex rendering, it has not yet been optimized for some basic shapes like diagonal lines.
For complex graphics, our Java2D implementation has up to 5x the performance of Sun's implementation, but simple Java-1.1-style graphics performance is significantly below that of MRJ 2.2.x, although better than in Mac OS X previews.
Anti-aliasing is on by default for text and graphics, but can be
turned off using the properties described in the section on
GUI customization, or by calling
setRenderingHint()
within your Java application.
Compatibility issues to note:
Known bugs:
drawLine()
) will
hit a serious bug that hangs the Java process, and may even
require a reboot. The workaround is to use drawLine()
in these cases, which is the more common approach.There is a new Mac OS look-and-feel which uses the Appearance
Manager to do its rendering, giving it full support for the Mac OS X
Aqua interface. This is now the default look-and-feel, and is set as
such in the swing.properties
file. Most Swing-based
applications have preference settings that allow you to switch the
look-and-feel.
Things to note about the Mac OS look-and-feel:
Known bugs:
Known problems with event handling:
There are many system properties that can be set (via a
.properties
file in your home directory, via
MRJAppBuilder, via Project Builder, or on the java
command line) to customize various aspects of the GUI:
Property Default Function com.apple.macosx.AntiAliasedTextOn true Use anti-aliasing when rendering
text. com.apple.macosx.AntiAliasedGraphicsOn true Use anti-aliasing when rendering
graphics. com.apple.macos.useMDEF true Uses a custom Carbon menu definition
(MDEF) for Swing menus in the Mac menu bar. This allows
Swing menus to draw arbitrary content. com.apple.macos.useScreenMenuBar false Puts Swing menus in the Mac OS menu bar,
if using the Aqua look and feel. com.apple.mrj.application.growbox.intrudes true Resizable window's grow-box intrudes into
AWT content (if turned off, bottom of window is pushed down
15 pixels.) com.apple.mrj.application.live-resize true Enables live resizing of
windows. com.apple.mrj.application.apple.menu.about.name none If defined, an "About" command will be
added to the top of the application menu, and can be
detected by registering a
com.apple.mrj.AboutHandler.
The properties that apply to windows can be changed at runtime, but the changes apply only to windows that do not yet have peers (those that have not yet been shown or packed).
Unsigned applets can't access the above properties. The one
current exception is com.apple.macos.useScreenMenuBar. If
you need to use other internal properties from an applet, you can
grant permission to access them by adding a line like the following
to your system-wide policy file, which is located at
${JAVA_HOME}/lib/security/java.policy
:
java.util.PropertyPermission "
internal.property.goes.here
", "read,write";
If you are running an AWT-based application as an RMI client, you
may encounter security exceptions when you launch the application. To
work around this, add the following entries to your system-wide
java.policy
file, which is located at
${JAVA_HOME}/lib/security/java.policy
:
java.util.PropertyPermission
"com.apple.openglactive", "read";
java.util.PropertyPermission "macosx.aatextactive", "read";
java.util.PropertyPermission "macosx.fmtextactive", "read";
java.util.PropertyPermission "com.apple.macos.xUseQD", "read";
java.util.PropertyPermission
"com.apple.macos.xDontUseWindowGroups", "read";
java.awt.AWTPermission "accessEventQueue", "";
This can be done in the section for all code, or on a case-by-case basis in a separate policy file you specify on the command line.
Other known problems with RMI:
Java on Mac OS X now supports sound output. However, audio input is not currently supported.
Mac OS X implements JDirect3, which allows access to pre-existing native code libraries from Java. JDirect2 code will require minor modifications to run under JDirect3. JDirect1, which has been deprecated since 1997, is no longer supported.
The JDirect sample code supplied in source form in the MRJ 2.2 SDK will not work on OS X. That code is not Carbonized and it does not use JDirect3.
Read Compatibility between JDirect 2 and JDirect 3 for more information on how to convert JDirect2 code to use JDirect3 on Mac OS X.
It is imperative that you synchronize all Toolbox calls. Java threads are native Mach threads and can preempt Toolbox calls made by the host app or by other Java threads. Carbon is not yet reentrant or thread-safe, and reentrant calls can corrupt memory or crash the app, so it's imperative that only one thread be inside Carbon at any time.
The correct method for Toolbox synchronization has changed since
Public Beta. Java on Mac OS X GM no longer supports the
synchronization method (Toolbox.LOCK
) described in the
Public Beta Java release notes. The correct way to call the Toolbox
(aka Carbon) from Java on Mac OS X GM is:
import com.apple.mrj.macos.carbon.CarbonLock; try { CarbonLock.acquire(); <Carbon call here> } finally { CarbonLock.release(); }
This way the CarbonLock handling can easily be reversed for JDirect callbacks.
Be sure to use CarbonLock around all Carbon calls. Since threads are preemptive on Mac OS X, one should hold the CarbonLock for the very least amount of time possible. Deadlocks occur more often when the CarbonLock is held too long.
Also, don't do anything which may throw exceptions in the
finally
block that calls
CarbonLock.release()
. Structure your code so that the
CarbonLocking is separate from other finally
blocks.
To help debug JDirect on Mac OS X, if you define a shell variable
named JDIRECT_VERBOSE
, JDirect will write verbose
loading info to stderr. Note that this only works when launching java
code from the command line--not when double-clicking the bundled
application in the Finder. But you can launch any double-clickable
application from the command line by specifying the path to the
application's executable.
For example, to set the shell variable, and then launch an
application called Foo.app
from the command line, you
would do the following in csh:
% setenv JDIRECT_VERBOSE % /path/Foo.app/Contents/MacOS/Foo
The class MethodClosureUPP was created for use on Mac OS 9 and is not supported on Mac OS X (the design of that class assumes the existence of MixedMode). If you are using Toolbox callbacks and want code that will run on Mac OS 9 or Mac OS X, you will need to have a helper class that creates a new MethodClosureUPP when on Mac OS 9 or a new MethodClosure when on Mac OS X.
For this release of Mac OS X, any use of JDirect will cause Carbon to be initialized, a dock entry added, and a menu bar installed. This was necessary because Carbon is not thread safe and must be initialized from the correct thread. A future release of JDirect will provide a way to specify which JDirect native calls do not load Carbon, and thus are safe to run without initializing Carbon.
Normally, your JDirect_MacOSX String
is a full path
to a dylib which is the standard packaging for shared mach-o code on
Mac OS X. But you can also specify a full path to a CFBundle. The
CFBundle path name must end in ".bundle
" and be a
properly constructed directory. The CFBundle supports both mach-o
code and CFM code. See the Bundle
Services documentation for more details.
New functionality in Mac OS X has enabled us to replace JManager (the embedding technology for MRJ 2.x on Mac OS 9) with a Carbon-based Java embedding API. JManager is not supported in Mac OS X. The interfaces to the new API are the headers <JavaVM/JavaApplet.h>, <JavaVM/JavaControl.h> and <JavaVM/JavaErrors.h>.
The new Java Embedding API is smaller and simpler than JManager. The functionality previously supplied by JManager is available through the JNI Invocation API, the CoreFoundation API, or is unnecessary and has been removed. The functions that remain in the new Java Embedding API are primarily applet embedding and utility functions.
Native applications that want to invoke Java should launch a Java
VM using the standard JNI Invocation API, and call
CreateSafeEnvironment()
on the main thread.
Only native applications that want to embed a Java frame into their own windows need to use the new Java Embedding control creation APIs in <JavaVM/JavaControl.h>. These create a "Java Control" -- a standard Control Manager control that contains a Java applet. The control creation APIs take a native WindowRef that references the window into which the Java Control is to be embedded.
Known problems with the Java Embedding API:
The MRJToolkit utility routines from previous versions of MRJ are present in this release, but there are differences.
Several of the MRJToolkit routines do not work:
openURL()
, setDefaultFileCreator()
, and
setDefaultFileType()
. In a future release,
openURL()
may be implemented, but the other two will be
removed entirely.
The MRJ
Thing
Handler
interfaces (MRJAboutHandler
,
MRJCoercionHandler
, MRJOpenDocumentHandler
,
MRJPrintDocumentHandler
, MRJQuitHandler
)
will not work until the AWT is initialized. For packaged
double-clickable applications, the AWT is initialized before your
application's main()
is called. If you launch your java
application from the command line, you must either register your
handlers after your code has initialized the AWT, or force the AWT to
be initialized via a simple snippet such as:
new Frame().pack();
Every Java application with UI automatically gets an Apple menu
and an application menu. The application menu follows the standard
Aqua guidelines and contains a Quit menu item. By default that Quit
menu item will call System.exit()
. If you have your own
Quit (or Exit) item in your own menu, then when running on Mac OS X,
you should change your menu to remove the Quit item. You can install
an MRJQuitHandler which will be called when the user chooses the Quit
menu item in the application menu.
Known problems with MRJQuitHandler:
MRJQuitHandler
cannot directly field events.
For instance, you cannot run a modal dialog which asks the user to
confirm the Quit. The workaround is to create a new thread and run
the modal dialog on it.MRJQuitHandler
.Project Builder is a complete development environment that supports editing, compiling, packaging, running, and debugging Java applications, using the Java runtime on Mac OS X. See the Project Builder documentation for more information.
MRJAppBuilder is a utility for packaging already-compiled Java applications to run on Mac OS X. MRJAppBuilder constructs applications in the new Carbon application bundle format. In order to package your application, you must specify (at a minimum) the main class name and the location of the output file. If you are not merging your Java class or jar files into the output, you will need to add them to the classpath. Each of these values is settable from within the Application panel.
The main class field is where you must enter the name of the class
that contains main()
. This field represents the value of
the property com.apple.mrj.application.main
. Remember to
include any package information, such as
com.foo.myclass
. You can also press the "Choose..."
button to choose a jar file that contains the main class.
The classpath field allows you to modify the classpath. Usually, this will be automatically set to point to the jar file that you're bundling into your application. In the case where you wish to use a jar file that remains outside the application bundle, you need to add a classpath entry of the form:
$APP_PACKAGE is a special path string that represents the application bundle directory.
The last required field is the output file field. You must specify the name and location of the output file. You may either enter the path in the text field provided or you may press the "Set..." button to set the location of the output file using the file chooser dialog.
You can add a custom icon to your application. Click on the icon
in the Output file section to bring up a file chooser dialog for
selecting an icns
file.
Using the other tabbed panels is optional. The Mac OS X panel allows you to set values specific to the Mac OS X application bundle format. If you do not specify the CFBundleExecutable or CFBundleName, they will be set based on the name of the output file you choose.
The Java Properties panel allows you to set Java runtime properties. The main and classpath fields are not editable--they can only be set in the Application panel. The remaining properties are the standard properties supported by Java on Mac OS along with their default values. To set additional properties not listed in the table, simply add them to the end of the list. In previous versions of MRJAppBuilder, you were required to create a configurations file defining the Java runtime properties. This panel is a replacement for the configurations file.
The Merge Files panel provides a means for adding files to
the application, such as zips or jars. Choose the "Add..." button to
add files to the list. Each item added to the merge list will be
copied into the application's Contents/Resources/Java/
directory. Each item you add to the merge list gets automatically
added to the classpath.
Console output from packaged Java applications built by MRJAppBuilder, or from applets running inside Applet Launcher, appears in the system console, which can be viewed by launching /Applications/Utilities/Console.
If you want application output to appear in a Terminal window,
you'll have to launch the application from that Terminal. You can
either use a "java
" command directly with your jar or
class files, as described in Launching
java from the command line below, or launch the packaged
application from the Terminal by specifying the path to the
executable. Assuming the current directory is the parent directory of
the application, you launch a packaged application like this:
MyJavaApp.app/Contents/MacOS/MyJavaApp
There are magic strings for IO redirection: $CONSOLE
causes output to be displayed in a Java console window.
$SYSTEM
leaves stderr and stdout as is (directed to
Console for double-clickable applications, or directed to the parent
shell for applications launched from the command line).
When you build your application with MRJAppBuilder or Project
Builder, the current Java working directory defaults to the
application bundle directory. For example, if you've built an
application named myApp.app
inside the folder
/Volumes/HD/myJavaApplications/
, then the current
directory would be
/Volumes/HD/myJavaApplications/myApp.app/
. As a result,
all of your classpath entries for jar files merged into your
application would be of the form
Contents/Resources/Java/myApp.jar
. Note that the
Contents
folder resides directly inside
myApp.app
.
You can override the current Java working directory by setting the
property com.apple.mrj.application.workingdirectory
.
This property must be an absolute path, or must start with
$APP_PACKAGE
, which is a special path string that
represents the application bundle directory. Therefore, in this
example, these are equivalent current working directory
specifications:
com.apple.mrj.application.workingdirectory
=
$APP_PACKAGE/Contents/Resources/Java
com.apple.mrj.application.workingdirectory
=
/Volumes/HD/myJavaApplications/myApp.app/Contents/Resources/Java
Let's assume you have a simple Java program, such as HelloWorld.
Use javac
and jar
in the Terminal (in
/Applications/Utilities/
) to compile the source and
create a jar file named HelloWorld.jar
. Launch
MRJAppBuilder from /Developer/Applications/
. The active
panel will be the Application panel.
Step 1: Set the Main classname.
Click on the "Choose..." button and navigate to and select the
HelloWorld.jar
file. Click on "Select". In the "Choose Main Class" dialog, you should see only the nameHelloWorld
, since there is only one class containing amain()
method. Click "OK". The main classname field should be automatically filled out and the classpath updated with the itemContents/Resources/Java/HelloWorld.jar
.Step 2: Set the Output file.
Click on the "Set..." button and navigate to the desired output directory. In the "Select" dialog, type the name of the output file in the "Name" field. If you don't enter one, the default will be the name of the folder you last clicked on. Click on "Select". The Output file field should be filled out with the full path to the output file. If you don't append a "
.app
" extension to the name of your application, MRJAppBuilder will add the extension when it builds the application.Step 3: Build the application
Click on "Build Application". That's it! Your application can now be launched from the Finder. The
HelloWorld.jar
file was copied into the application, so you can move the application to any location and it will run.Notes on the example:
- All of the text fields in the Application panel are editable, so instead of using the dialogs, you could type the values for each field directly.
- For more complex applications that have more than one jar file, use the Merge Files panel to add those files to your application.
- We recommend that you add jar files to your application as opposed to individual class files.
Known problems with MRJAppBuilder:
Applet Launcher allows you to run Java applets without the
overhead of launching a web browser. Applet Launcher provides a user
interface around the sun.applet.AppletViewer
class, with
more features than the appletviewer command-line tool from
Sun, which is based on the same class. You can enter the path to an
applet using its fully-qualified URL, and then press the Launch
button. For example, entering the following URL will launch the Sun
Tumbling Duke example applet:
http://java.sun.com/applets/other/TumblingDuke/index.html
Applet Launcher has an Applets menu that displays all applets
listed in the /Developer/Examples/Java/Applets
directory. These applets are provided by Sun Microsystems as
examples.
JDK-style command-line launching from the Terminal app is fully supported (as are all your favorite JDK tools like javac and rmic). You can still use "java" to launch apps and "appletviewer" to launch applets. (Invoking these with no arguments will print a brief help message.) The Terminal window serves as the Java console. You can kill a Java process by activating the Terminal window that launched it and pressing Ctrl-C.
Known problems with launching from the command line:
Copyright © 2001 Apple Computer, Inc.