Hi,

I had classloading blocks on m_classLocks in a JamVM (GNU Classpath) 
environment. Details in the thread starting at 
http://mail-archives.apache.org/mod_mbox/felix-dev/201311.mbox/%[email protected]%3e
 .

It ended up being "solved" by 'synchronized'ing findClass in the 
BundleClassLoader.

Dan.


On 17 Mar 2014, at 13:07, Stefan Egli wrote:

> 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]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to