On 3/14/14, 05:26 , Stefan Egli wrote:
Hi,
I just ran into the famous deadlock with Java 6 where the same class is being
loaded from two different bundles (also see FELIX-3953). This happened on a
startup of a CQ instance.
I'll add more analysis details but my question is: what is the suggested best
practice to handle this issue?
* Use '-XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass' as suggested in [0] and
[1]? But then again [1] says "You must treat it as unstable, experimental,
temporary, unsupported".
This is your only option if you are not able to use Java 7.
* Or would it be worth while to reconsider fixing FELIX-3953?
Unless we modify the JRE, there is no way to fix it. The Felix framework
doesn't hold locks while class loading.
-> richard
Here's more details (see thread-dumps below):
* Thread 158 (on behalf on bundle X) wants to load class A which is part of
bundle Y - hence goes via getClassByDelegation - then does a
BundleWiringImpl$BundleClassLoader.findClass
* before Thread 158 continues VM threading decides to give Thread 156 some
execution time:
* Thread 156 now wants to load same class A, but this time directly on behalf
of bundle Y.
* Due to [1] Thread 156 internally does a synchronized loadClassInternal,
thus holds the lock on 6f025d710 (the BundleClassLoader of bundle Y) (I was
able to verify this by hooking the deadlocked-VM to a debugger, which indicated
exactly this)
* Thread 156 now continues into
BundleClassLoader.findClass(BundleWiringImpl.java:2115) where it has to do a
m_classLocks.wait() - since Thread 158 earlier marked the BundleClassLoader 'in
use/locked for class A'.
* Thread 158 on the other hand continues the findClass execution, eventually
walks into checkCerts, which is synchronized(this), which Thread 156 holds
* and we have the famous classloading deadlock.
Cheers,
Stefan
--
[0] https://issues.apache.org/jira/browse/FELIX-3953
[1] http://underlap.blogspot.de/2006/11/experimental-fix-for-sunbug-4670071.html
PS: Used org.apache.felix.framework 4.3.0.R1558704 - which is a
snapshot-release as of SVN revision 1558704
"Thread-158" daemon prio=5 tid=7f83a4cbd800 nid=0x25b73e000 waiting for monitor
entry [25b73c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.ClassLoader.checkCerts(ClassLoader.java:788)
- waiting to lock <6f025d710> (a
org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5)
at java.lang.ClassLoader.preDefineClass(ClassLoader.java:493)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2297)
at
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1519)
at
org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:77)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1973)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at
org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWiringImpl.java:1392)
at
org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImpl.java:1571)
at
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1502)
at
org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:77)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1973)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[class A being loaded from a class of bundle X]
"Thread-156" daemon prio=5 tid=7f83a57ac800 nid=0x25b36b000 in Object.wait()
[25b369000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.findClass(BundleWiringImpl.java:2115)
- locked <6f788bf40> (a java.util.HashMap)
at
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1519)
at
org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:77)
at
org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1973)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
[class A being loaded from a class of bundle Y]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]