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]

Reply via email to