Be more flexible and allow misbehaving threads to continue to issue class load
requests on class loaders from disposed of bundle wirings. Also attempt to
give a reasonable exception when a new class load request is made on a class
loader from a disposed bundle wiring. (FELIX-3907)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1452999 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 47c3e95..e139fbd 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleWiringImpl.java
@@ -641,13 +641,20 @@
         return m_revision;
     }
 
-    public synchronized ClassLoader getClassLoader()
+    public ClassLoader getClassLoader()
     {
         if (m_isDisposed)
         {
             return null;
         }
-        if (m_classLoader == null)
+        return getClassLoaderInternal();
+    }
+
+    private synchronized ClassLoader getClassLoaderInternal()
+    {
+        // Only try to create the class loader if the bundle
+        // is not disposed.
+        if (!m_isDisposed && (m_classLoader == null))
         {
             // Determine which class loader to use based on which
             // Java platform we are running on.
@@ -1354,7 +1361,17 @@
             throw new ClassNotFoundException(name);
         }
 
-        return getClassLoader().loadClass(name);
+        ClassLoader cl = getClassLoaderInternal();
+        if (cl == null)
+        {
+            throw new ClassNotFoundException(
+                "Unable to load class '"
+                + name
+                + "' because the bundle wiring for "
+                + m_revision.getSymbolicName()
+                + " is no longer valid.");
+        }
+        return cl.loadClass(name);
     }
 
     private boolean isFiltered(String name)
@@ -1469,9 +1486,24 @@
                 // If not found, try the revision's own class path.
                 if (result == null)
                 {
-                    result = (isClass)
-                        ? (Object) ((BundleClassLoader) getClassLoader()).findClass(name)
-                        : (Object) m_revision.getResourceLocal(name);
+                    if (isClass)
+                    {
+                        ClassLoader cl = getClassLoaderInternal();
+                        if (cl == null)
+                        {
+                            throw new ClassNotFoundException(
+                                "Unable to load class '"
+                                + name
+                                + "' because the bundle wiring for "
+                                + m_revision.getSymbolicName()
+                                + " is no longer valid.");
+                        }
+                        result = (Object) ((BundleClassLoader) cl).findClass(name);
+                    }
+                    else
+                    {
+                        result = (Object) m_revision.getResourceLocal(name);
+                    }
 
                     // If still not found, then try the revision's dynamic imports.
                     if (result == null)
@@ -1954,6 +1986,21 @@
         {
             Class clazz = null;
 
+            // Do a quick check to try to avoid searching for classes on a
+            // disposed class loader, which will avoid some odd exception.
+            // This won't prevent all weird exception, since the wiring could
+            // still get disposed of after this check, but it will prevent
+            // some, perhaps.
+            if (m_wiring.m_isDisposed)
+            {
+                throw new ClassNotFoundException(
+                    "Unable to load class '"
+                    + name
+                    + "' because the bundle wiring for "
+                    + m_wiring.m_revision.getSymbolicName()
+                    + " is no longer valid.");
+            }
+
             // Search for class in bundle revision.
             if (clazz == null)
             {