Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 347578 - [OTRE] JVM hang while loading class sun.misc.Cleaner
Summary: [OTRE] JVM hang while loading class sun.misc.Cleaner
Status: VERIFIED FIXED
Alias: None
Product: Objectteams
Classification: Tools
Component: OTDT (show other bugs)
Version: 0.8   Edit
Hardware: PC Linux
: P2 critical (vote)
Target Milestone: 2.0 RC3   Edit
Assignee: Stephan Herrmann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-29 08:40 EDT by Stephan Herrmann CLA
Modified: 2011-06-02 11:49 EDT (History)
0 users

See Also:


Attachments
proposed fix (1.35 KB, patch)
2011-05-29 08:45 EDT, Stephan Herrmann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
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