JDK-4710324 : rmic uses AWT ?!
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris_2.6
  • CPU: sparc
  • Submitted: 2002-07-01
  • Updated: 2004-04-16
  • Resolved: 2004-04-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.3.1_12 12Fixed
Related Reports
Relates :  
Description
Name: gm110360			Date: 07/01/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


FULL OPERATING SYSTEM VERSION :

SunOS bcalmac-u10 5.6 Generic_105181-28 sun4u sparc
SUNW,Ultra-5_10

EXTRA RELEVANT SYSTEM CONFIGURATION :
I am running rmic in an automatic build environment WITHOUT
A DISPLAY (env var DISPLAY is not set).

A DESCRIPTION OF THE PROBLEM :
I am using rmic -iiop to compile the implemetation of a
remote object. Among other thing the object references
AdventNet SNMP library which contains some GUI classes.

During compilation rmic instantiates classes in such a way
that it gets to AWT and crashes if DISPLAY is not set (our
automatic build system does not have DISPLAY set).

Please note that neither the interface nor the
implementation refer to AWT. It is just that the library
that I'm using has also some AWT classes.

The compiler should be more conservative about
instantiating classes.

Here is the stacktrace:




REGRESSION.  Last worked in version 1.3.1

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Open a terminal without DISPLAY set
2. Use rmic -iiop to compile a class that references GUI
classes



EXPECTED VERSUS ACTUAL BEHAVIOR :
rmic tries to open a display that is not available. rmic
should not rely on a display.

My class does not reference any GUI class. rmic should
instantiate at most the remote interfaces and
implementations; it shouldn't go through all the library.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
/auto/ntgtoolsdist/localsol/java/j2sdk1.4.0/bin/rmic -iiop  -
sourcepath :/vob/ntg/dev/java/inf/snmp: -
d /vob/ntg/dev/resources/java/classes/common -J-mx64m -g  -
classpath /auto/ntgtoolsdist/apps/java/archives/AdventNetSnmp3_3.2.jar
com.cisco.vpnsc.snmp.trap.TrapMonitorImpl
java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the
value of the DISPLAY variable.
        at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method)
        at sun.awt.X11GraphicsEnvironment.<clinit>
(X11GraphicsEnvironment.java:126)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:130)
        at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment
(GraphicsEnvironment.java:62)
        at sun.awt.motif.MToolkit.<clinit>(MToolkit.java:70)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:130)
        at java.awt.Toolkit$2.run(Toolkit.java:712)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.Toolkit.getDefaultToolkit(Toolkit.java:703)
        at java.awt.datatransfer.SystemFlavorMap$2.run(SystemFlavorMap.java:196)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.awt.datatransfer.SystemFlavorMap.<init>
(SystemFlavorMap.java:192)
        at java.awt.datatransfer.SystemFlavorMap.getDefaultFlavorMap
(SystemFlavorMap.java:156)
        at java.awt.dnd.DropTarget.<clinit>(DropTarget.java:54)
        at sun.misc.Unsafe.ensureClassInitialized(Native Method)
        at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor
(UnsafeFieldAccessorFactory.java:20)
        at sun.reflect.ReflectionFactory.newFieldAccessor
(ReflectionFactory.java:122)
        at java.lang.reflect.Field.acquireFieldAccessor(Field.java:779)
        at java.lang.reflect.Field.getFieldAccessor(Field.java:760)
        at java.lang.reflect.Field.getLong(Field.java:398)
        at com.sun.corba.se.internal.io.ObjectStreamClass$2.run
(ObjectStreamClass.java:501)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.corba.se.internal.io.ObjectStreamClass.init
(ObjectStreamClass.java:488)
        at com.sun.corba.se.internal.io.ObjectStreamClass.lookupInternal
(ObjectStreamClass.java:150)
        at com.sun.corba.se.internal.io.ObjectStreamClass.lookup
(ObjectStreamClass.java:83)
        at
com.sun.corba.se.internal.io.ObjectStreamClass.getActualSerialVersionUID
(ObjectStreamClass.java:204)
        at com.sun.corba.se.internal.util.RepositoryId.createHashString
(RepositoryId.java:593)
        at com.sun.corba.se.internal.util.RepositoryId.createForJavaType
(RepositoryId.java:740)
        at com.sun.corba.se.internal.util.RepositoryId.createForAnyType
(RepositoryId.java:816)
        at sun.rmi.rmic.iiop.Type.setRepositoryID(Type.java:984)
        at sun.rmi.rmic.iiop.CompoundType.initialize(CompoundType.java:774)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:248)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.ClassType.initParents(ClassType.java:188)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:219)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.ClassType.initParents(ClassType.java:188)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:219)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.ClassType.initParents(ClassType.java:188)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:219)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2294)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.AbstractType.initialize(AbstractType.java:159)
        at sun.rmi.rmic.iiop.AbstractType.forAbstract(AbstractType.java:81)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:876)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.RemoteType.isConformingRemoteInterface
(RemoteType.java:213)
        at sun.rmi.rmic.iiop.RemoteType.initialize(RemoteType.java:162)
        at sun.rmi.rmic.iiop.RemoteType.forRemote(RemoteType.java:81)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:864)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2294)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.ValueType.initialize(ValueType.java:237)
        at sun.rmi.rmic.iiop.ValueType.forValue(ValueType.java:108)
        at sun.rmi.rmic.iiop.CompoundType.makeType(CompoundType.java:921)
        at sun.rmi.rmic.iiop.CompoundType$Method.<init>(CompoundType.java:2313)
        at sun.rmi.rmic.iiop.CompoundType.addAllMethods(CompoundType.java:1320)
        at sun.rmi.rmic.iiop.RemoteType.isConformingRemoteInterface
(RemoteType.java:213)
        at sun.rmi.rmic.iiop.RemoteType.initialize(RemoteType.java:162)
        at sun.rmi.rmic.iiop.RemoteType.forRemote(RemoteType.java:81)
        at sun.rmi.rmic.iiop.CompoundType.addRemoteInterfaces
(CompoundType.java:1422)
        at sun.rmi.rmic.iiop.ImplementationType.initialize
(ImplementationType.java:157)
        at sun.rmi.rmic.iiop.ImplementationType.forImplementation
(ImplementationType.java:83)
        at sun.rmi.rmic.iiop.StubGenerator.getTopType(StubGenerator.java:124)
        at sun.rmi.rmic.iiop.Generator.generate(Generator.java:259)
        at sun.rmi.rmic.Main.doCompile(Main.java:526)
        at sun.rmi.rmic.Main.compile(Main.java:130)
        at sun.rmi.rmic.Main.main(Main.java:761)
error: An error has occurred in the compiler; please file a bug report
(http://java.sun.com/cgi-bin/bugreport.cgi).
1 error


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER WORKAROUND :
use rmic only when DISPLAY is available. Not applicable in
our automated build system.
(Review ID: 158679) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.3.1_12 generic FIXED IN: 1.3.1_12 INTEGRATED IN: 1.3.1_12
14-06-2004

SUGGESTED FIX --- IBM Fix Details --- The fix for the problem on IBM platforms is in AWT code. java.awt.dnd.DropTarget contains a static variable initialiser that, as part of the classloading spec, is executed when the class is loaded. This initialiser results in the AWT being initialised, with the side effect that this class cannot be interrogated via the Reflection API (for instance, using the serialver tool) on a Unix platform without having a valid DISPLAY environment set. A. DETAILS ABOUT THE PROBLEM XXX reported that running rmic using the "-mnt" parameter against a supplied testcase resulted in: java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable. B. RECREATION STEPS Ensure that the DISPLAY environment variable is not set or points to an invalid X display. Then run: serialver java.awt.dnd.DropTarget for the simple testcase. XXX encountered this problem using the rmic compiler. This can be demonstrated using the following SimpleEJB.java: public interface SimpleEJB { class MyBeans extends java.beans.Beans implements java.io.Serializable { } public abstract MyBeans findBeans(String s) throws java.rmi.RemoteException; } Compile the above using javac and then run: rmic -mnt SimpleEJB -- PROBLEM ANALYSIS -- rmic fails because, as part of the processing, it calculates hashcodes based on the fields and return and parameter types of the interface methods in the target class. These fields are discovered via the Reflection API. java.beans.Beans has methods which return AWT based classes. Most of these are derived from java.awt.Component. This class has a field of type java.awt.dnd.DropTarget. Because Reflection is used DropTarget is loaded into the JVM. As part of the classloading spec static initializers and static variable initializers are run when the class is loaded. This causes problems for DropTarget, as its static variable initializer for its defaultFlavorMap field eventually results in a call to java.awt.Toolkit.getDefaultToolkit() from java.awt.datatransfer.SystemFlavorMap. This attempts to initialise the AWT, which on a UNIX based platform (e.g. AIX, Linux, z/OS) requires an X11 windows server. A valid DISPLAY environment variable must be set, therefore, even though rmic is not going to be doing any graphics work. -- PROBLEM RESOLUTION -- Delay the initialisation of the defaultFlavorMap field in java.awt.dnd.DropTarget. We do not need this field to have a value when the class is loaded, but it should be set before we create an instance of DropTarget. In order to delay the initialisation we need to change the declaration of defaultFlavorMap so that it is no longer final: static private final FlavorMap defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap(); becomes static private FlavorMap defaultFlavorMap; The following three lines are added to the beginning of public void setFlavorMap(FlavorMap fm); to ensure that defaultFlavorMap is set before attempting to assign flavorMap. if (defaultFlavorMap == null) { defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap(); } Finally the flavorMap field must be changed from: private transient FlavorMap flavorMap = defaultFlavorMap; to: private transient FlavorMap flavorMap = (defaultFlavorMap == null ? defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap() : defaultFlavorMap); ###@###.### 2004-01-29 ###@###.### 2004-03-01 Following file change proposed for 1.3.1_XX. 1.4.2_04 does not exhibit the behaviour so no changes needed. Tiger does not use static initializers so fix is not applicable to tiger as well. --- DropTarget.java Thu Feb 26 11:52:10 2004 *** 46,56 **** /* * default FlavorMap for the system */ ! static private final FlavorMap defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap(); /** * Construct a new DropTarget given the <code>Component</code> * to associate itself with, an <code>int</code> representing * the default acceptable action(s) to --- 46,56 ---- /* * default FlavorMap for the system */ ! static private FlavorMap defaultFlavorMap; /** * Construct a new DropTarget given the <code>Component</code> * to associate itself with, an <code>int</code> representing * the default acceptable action(s) to *** 387,396 **** --- 387,399 ---- * <P> * @param fm set the new <code>FlavorMap</code>, or null for default */ public void setFlavorMap(FlavorMap fm) { + if (defaultFlavorMap == null) { + defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap(); + } flavorMap = fm == null ? defaultFlavorMap : fm; } /** * Notify the DropTarget that it has been associated with a Component *** 713,723 **** /* * The FlavorMap */ ! private transient FlavorMap flavorMap = defaultFlavorMap; } --- 716,726 ---- /* * The FlavorMap */ ! private transient FlavorMap flavorMap = (defaultFlavorMap == null ? defaultFlavorMap = SystemFlavorMap.getDefaultFlavorMap() : defaultFlavorMap); }
11-06-2004

WORK AROUND Might a workaround for this bug (for Tiger, at least) be to run the tool with the following option? -X-Djava.awt.headless=true ###@###.### 2004-01-28
28-01-2004

EVALUATION Re-assigning this bug to idl/rmic-iiop because the behavior is specific to the "-iiop" mode of rmic (the JRMP mode does not load application classes into the virtual machine). ###@###.### 2002-07-08 ###@###.### 2002-07-11 This seems to be a bug. Reopened as IBM have provided suggested fix - their fix wholely within AWT code. ###@###.### 2004-01-29 ###@###.### 2004-01-29
11-07-2002