Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 347578

Summary: [OTRE] JVM hang while loading class sun.misc.Cleaner
Product: [Tools] Objectteams Reporter: Stephan Herrmann <stephan.herrmann>
Component: OTDTAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED FIXED QA Contact:
Severity: critical    
Priority: P2    
Version: 0.8   
Target Milestone: 2.0 RC3   
Hardware: PC   
OS: Linux   
Whiteboard:
Attachments:
Description Flags
proposed fix none

Description Stephan Herrmann CLA 2011-05-29 08:40:45 EDT
When running the Order System example on a 1.6 JVM
it reproducably hangs during system start-up.
When trying to capture the hang in the debugger
the JVM crashes as soon as I try to open a thread in the debug view
after first suspend.

Using kill -3 I could see this:

"Reference Handler" daemon prio=10 tid=0x7269c800 nid=0x1b17 waiting for monitor entry [0x723b7000..0x723b9080]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:293)
	- waiting to lock <0xadd002b8> (a sun.misc.Launcher$AppClassLoader)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
	at org.apache.bcel.classfile.Field.<clinit>(Field.java:34)
	at org.apache.bcel.classfile.ClassParser.readFields(ClassParser.java:236)
	at org.apache.bcel.classfile.ClassParser.parse(ClassParser.java:143)
	at org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer.internalTransform(ObjectTeamsTransformer.java:163)
	at org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer.transform(ObjectTeamsTransformer.java:96)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:169)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:365)
	at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:123)

"main" prio=10 tid=0x0890d800 nid=0x1b11 in Object.wait() [0xb76ce000..0xb76d0158]
   java.lang.Thread.State: RUNNABLE
	at org.apache.bcel.classfile.ClassParser.readFields(ClassParser.java:236)
	at org.apache.bcel.classfile.ClassParser.parse(ClassParser.java:143)
	at org.apache.bcel.util.ClassLoaderRepository.loadClass(ClassLoaderRepository.java:94)
	at org.eclipse.objectteams.otre.RepositoryAccess.lookupClass(RepositoryAccess.java:66)
	at org.eclipse.objectteams.otre.ObjectTeamsTransformation.addTeamInitializations(ObjectTeamsTransformation.java:688)
	at org.eclipse.objectteams.otre.ObjectTeamsTransformation.checkReadClassAttributes(ObjectTeamsTransformation.java:590)
	at org.eclipse.objectteams.otre.SubBoundBaseMethodRedefinition.doTransformInterface(SubBoundBaseMethodRedefinition.java:52)
	at org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer.internalTransform(ObjectTeamsTransformer.java:189)
	at org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer.transform(ObjectTeamsTransformer.java:99)
	- locked <0xadd002b8> (a sun.misc.Launcher$AppClassLoader)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:169)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:365)
	at java.lang.ClassLoader.defineClass1(Native Method)
 ...

Stepping up-to shortly before the hang I see that the "Reference Handler"
thread is trying to load class sun.misc.Cleaner. The class loader to be used is,
however, locked by thread "main". OTOH, "Reference Handler" is initializing
class Field, which is the next one thread "main" is waiting to load -> deadlock.

In this particular scenario I was even passing 
  -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass
which didn't help though. It actually seems to be a JVM bug that thread
"Reference Handler" needs to wait for the class loader owned by thread "main".

The problem does not occur with any of these: openjdk-6, sun jdk 1.5,  jdk 1.7.

E.g. on 1.7 the ReferenceHandler is still waiting for incoming Finalizers
(field 'pending') until the main method is entered, by what time the transformer
is probably fully initialized (incl. bcel). Thus, loading class Cleaner happens
much later - in a more stable state it seems.

By contrast, on 1.6 we already see Finalizers for FileInputStreams being
enqueued for cleanup while the main class (GUITest) is still being loaded
(i.e., the transformer&bcel are not yet fully initialized).
Comment 1 Stephan Herrmann CLA 2011-05-29 08:45:46 EDT
Created attachment 196845 [details]
proposed fix

This patch avoids the problem by excluding class sun.misc.Cleaner
from transforming.

There should be no harm in this as adapting this class with OT/J sounds
like a bad idea anyway.

By this change the "Reference Handler" thread no longer triggers
class loading from within the run loop, thus the deadlock can no longer occur.
Comment 2 Stephan Herrmann CLA 2011-05-29 08:46:59 EDT
Due to severity of this bug the patch has been released for 2.0 RC3.
Comment 3 Stephan Herrmann CLA 2011-06-02 11:49:40 EDT
Verified using build 201105311237