Bundle class loader should lock on the class loader object when not running
parallel capable, otherwise it should lock on the class locks map. (FELIX-4462)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1579270 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
index da6c0f5..beecd41 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -1857,24 +1857,33 @@
 
     public static class BundleClassLoaderJava5 extends BundleClassLoader
     {
+        static final boolean m_isParallel;
         static
         {
+            boolean registered = false;
             try
             {
                 Method method = BundleRevisionImpl.getSecureAction()
                     .getDeclaredMethod(ClassLoader.class, "registerAsParallelCapable", null);
 
-                 BundleRevisionImpl.getSecureAction().setAccesssible(method);
+                BundleRevisionImpl.getSecureAction().setAccesssible(method);
 
-                 method.invoke(null);
+                registered = ((Boolean) method.invoke(null)).booleanValue();
             }
             catch (Throwable th)
             {
                 // This is OK on older java versions
             }
+
+            m_isParallel = registered;
         }
 
-        private BundleWiringImpl m_wiring;
+        protected boolean isParallel()
+        {
+            return m_isParallel;
+        }
+
+        private final BundleWiringImpl m_wiring;
 
         public BundleClassLoaderJava5(BundleWiringImpl wiring, ClassLoader parent)
         {
@@ -1928,7 +1937,7 @@
         private static final int LIBNAME_IDX = 0;
         private static final int LIBPATH_IDX = 1;
         private final Map<String, Thread> m_classLocks = new HashMap<String, Thread>();
-        private BundleWiringImpl m_wiring;
+        private final BundleWiringImpl m_wiring;
 
         public BundleClassLoader(BundleWiringImpl wiring, ClassLoader parent)
         {
@@ -1944,6 +1953,11 @@
             m_wiring = wiring;
         }
 
+        protected boolean isParallel()
+        {
+            return false;
+        }
+
         public boolean isActivationTriggered()
         {
             return m_isActivationTriggered;
@@ -1961,7 +1975,8 @@
             Class clazz;
 
             // Make sure the class was not already loaded.
-            synchronized (m_classLocks)
+            Object lock = (isParallel()) ? m_classLocks : this;
+            synchronized (lock)
             {
                 clazz = findLoadedClass(name);
             }
@@ -2105,14 +2120,15 @@
                     // Before we actually attempt to define the class, grab
                     // the lock for this class loader and make sure than no
                     // other thread has defined this class in the meantime.
-                    synchronized (m_classLocks)
+                    Object lock = (isParallel()) ? m_classLocks : this;
+                    synchronized (lock)
                     {
                         Thread me = Thread.currentThread();
                         while (m_classLocks.containsKey(name) && (m_classLocks.get(name) != me))
                         {
                             try
                             {
-                                m_classLocks.wait();
+                                lock.wait();
                             }
                             catch (InterruptedException e)
                             {
@@ -2324,10 +2340,10 @@
                             wci.complete(wovenClass, wovenBytes, wovenImports);
                         }
 
-                        synchronized (m_classLocks)
+                        synchronized (lock)
                         {
                             m_classLocks.remove(name);
-                            m_classLocks.notifyAll();
+                            lock.notifyAll();
                         }
                     }