Hi Richard, (see below)
On 3/17/14 1:34 PM, "Richard S. Hall" <[email protected]> wrote: >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. I obviously don't know the details of the BundleClassLoader, so I can only speculate. But it seems the problem is its 'class locking' (m_classLocks). The assumption there seems, that BundleClassLoader.findClass() is always called unsynchronized. But this is clearly not the case in Java 6. So maybe Java 6 would need a special class loader which is synchronize-aware.. (in which case you could for example synchronize the BundleClassLoaderJava6.findClass() - given that the synchronization would be done by the VM anyway). Or introduce a 'proxy class loader' such that the VM would always only (be able to) synchronize the proxy.. (if that's feasible) Cheers, Stefan > >-> 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.h >>tml >> >> 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(B >>undleWiringImpl.java:2297) >> at >>org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegati >>on(BundleWiringImpl.java:1519) >> at >>org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.j >>ava:77) >> at >>org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(B >>undleWiringImpl.java:1973) >> at java.lang.ClassLoader.loadClass(ClassLoader.java:247) >> at >>org.apache.felix.framework.BundleWiringImpl.getClassByDelegation(BundleWi >>ringImpl.java:1392) >> at >>org.apache.felix.framework.BundleWiringImpl.searchImports(BundleWiringImp >>l.java:1571) >> at >>org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegati >>on(BundleWiringImpl.java:1502) >> at >>org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.j >>ava:77) >> at >>org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(B >>undleWiringImpl.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(B >>undleWiringImpl.java:2115) >> - locked <6f788bf40> (a java.util.HashMap) >> at >>org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegati >>on(BundleWiringImpl.java:1519) >> at >>org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.j >>ava:77) >> at >>org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(B >>undleWiringImpl.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] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

