I would like to report some bugs in the behaviour of the MacOS X
implementation of the GraphicsEnvironment.isHeadless method when
called in a headless environment, for example, a remote login window
that doesn't own the window server:
1. isHeadless doesn't actually check whether the environment is
headless, it just returns the value of the java.awt.headless system
property or false if this property is not set
2. In a headless environment in which the java.awt.headless system
property is not set, attempting to create a heavyweight component
causes a java.lang.InternalError rather than a HeadlessException
3. You get the InternalError even if you attempt to create a
lightweight component such as a Canvas or a Panel, unless
java.awt.headless is set to true, even though you should be allowed
to create such components in a headless environment
4. As a result of the InternalError, the AWT implementation is left
in an inconsistent state, and subsequent attempts to load an AWT
component cause a ClassNotFoundException
Strictly speaking, it's arguably the specification of the isHeadless
method that is at fault, and this is therefore an issue for Sun
rather than Apple, but the behaviour of Apple's Java implementation
differs from the behaviour of the Linux Java implementation in this
situation. In particular, the Linux/X11 Java implementation also
suffers from 1 and 2, but not from 3 and 4.
Note that everything works as expected if java.awt.headless is set to
true (regardless of whether the environment is actually headless or
not), but not if java.awt.headless is set to false (unless the
environment really isn't headless).
The basic problem is that the isHeadless method doesn't check whether
the environment is headless at all - it just checks the value of the
system property. However the rest of the AWT presumably depends on
the isHeadless method to do the right thing in a headless
environment. Hence, it's not really surprising that bad things happen
if isHeadless tells lies, but the Unix/X11 implementation behaves
better than the MacOS X implementation in this situation, and
arguably this difference in behavior is a bug in the MacOS X
implementation.
According to the JDK API, the GraphicsEnvironment.isHeadless method:
"Tests whether or not a display, keyboard, and mouse can be supported
in this environment."
In fact, it does no such thing - all it actually does is check
whether the java.awt.headless system property is set to true or not
(and check to see whether the X11 DISPLAY variable has been set in a
Linux/Solaris environment, but not whether the value is valid)
This means that if you run an AWT/Swing application in what MacOS X
considers to be a headless environment but you don't set
java.awt.headless to true, which shouldn't be necessary according to
the specification of isHeadless, you get a low-level MacOS X error
message:
kCGErrorRangeCheck : Window Server communications from outside of
session allowed for root and console user only
which turns into a java.lang.InternalError, "Can't connect to window
server - not enough permissions" rather than a
java.awt.HeadlessException.
This happens even if you're trying to do something that should be
allowed in a headless environment, such as creating a Panel rather
than a Frame.
Furthermore, the exception seems to leave the AWT implementation in
an inconsistent state because you get subsequent "class not found
exceptions" if you do anything that tries to load an AWT class.
Note that everything works as it should if you specify -
Djava.awt.headless=true, but this shouldn't be necessary according to
the specification of AWT Headless Support for JDK 1.4:
"To run our environment with a headless implementation, the follow
property may be specified at the java command line:
-Djava.awt.headless=true
If this property is not specified and a display, keyboard, and mouse
are not supported, then headless implementation is used by default."
Here are some tests that illustrate the difference in behaviour
between a headless X11 environment on Linux (with the DISPLAY
variable set to a bogus value), and a headless environment on Mac OS X:
Test 1 - create a Panel, which should be allowed in a headless
environment
Linux
$ java Test java.awt.Panel
isHeadless = false
Try to create a java.awt.Panel
Result = java.awt.Panel
[panel0,0,0,0x0,invalid,layout=java.awt.FlowLayout]
MacOS X
$ java Test java.awt.Panel
isHeadless = false
Try to create a java.awt.Panel
kCGErrorRangeCheck : Window Server communications from outside of
session allowed for root and console user only
Caught exception java.lang.InternalError: Can't connect to window
server - not enough permissions.
Test 2 - create a Frame followed by a Panel
Linux
$ java Test java.awt.Frame java.awt.Panel
isHeadless = false
Try to create a java.awt.Frame
Caught exception java.lang.InternalError: Can't connect to X11 window
server using 'foo' as the value of the DISPLAY variable. Can't
connect to X11 window server using 'foo' as the value of the DISPLAY
variable.
Try to create a java.awt.Panel
Result = java.awt.Panel
[panel0,0,0,0x0,invalid,layout=java.awt.FlowLayout]
MacOS X
$ java Test java.awt.Frame java.awt.Panel
isHeadless = false
Try to create a java.awt.Frame
kCGErrorRangeCheck : Window Server communications from outside of
session allowed for root and console user only
Caught exception java.lang.InternalError: Can't connect to window
server - not enough permissions.
Try to create a java.awt.Panel
Caught exception java.lang.NoClassDefFoundError: java.awt.Container
Note the unexpected expection from the attempt to create the JPanel,
which is caused by the first exception leaving the AWT implementation
in an inconsistent state.
Thanks,
Robert Stroud
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden