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".
 * Or would it be worth while to reconsider fixing FELIX-3953?

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]

Reply via email to