Applied patch (FELIX-962) to further improve our class loading delegation
hack.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@752985 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleImpl.java
index 858dc33..aa72d91 100644
--- a/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/searchpolicy/ModuleImpl.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.framework.searchpolicy;
+import java.lang.reflect.InvocationTargetException;
import org.apache.felix.moduleloader.*;
import java.io.IOException;
import java.io.InputStream;
@@ -1244,27 +1245,73 @@
return null;
}
- private boolean isClassNotLoadedFromBundle(Class clazz) throws ClassNotFoundException
+ private boolean isClassNotLoadedFromBundle(Class clazz)
{
- int idx = clazz.getName().lastIndexOf('$');
- if (idx > 0)
- {
- if (clazz.getClassLoader() != null)
- {
- Class outerClass = clazz.getClassLoader().loadClass(
- clazz.getName().substring(0, idx));
- if (outerClass != null)
- {
- clazz = outerClass;
- }
- }
- }
- return this.getClass().getClassLoader() != clazz.getClassLoader()
+ // If this is an inner class, try to get the enclosing class
+ // because we can assume that inner classes of class loaders
+ // are really just the class loader and we should ignore them.
+ clazz = getEnclosingClass(clazz);
+ return (this.getClass().getClassLoader() != clazz.getClassLoader())
&& !ClassLoader.class.isAssignableFrom(clazz)
&& !Class.class.equals(clazz)
&& !Proxy.class.equals(clazz);
}
+ private volatile static Method getEnclosingClassMethod = null;
+ private volatile static boolean getEnclosingClassMethodInitialized = false;
+
+ private static Class getEnclosingClass(Class clazz)
+ {
+ if (!getEnclosingClassMethodInitialized)
+ {
+ // Check if we have the getEnclosingClass() method available from
+ // JDK 1.5.
+ try
+ {
+ getEnclosingClassMethod =
+ Class.class.getDeclaredMethod("getEnclosingClass", null);
+ }
+ catch (NoSuchMethodException ex)
+ {
+ // Ignore it then.
+ }
+ getEnclosingClassMethodInitialized = true;
+ }
+ if (getEnclosingClassMethod != null)
+ {
+ try
+ {
+ Class enclosing = (Class) getEnclosingClassMethod.invoke(clazz, null);
+ clazz = (enclosing != null) ? enclosing : clazz;
+ }
+ catch (Throwable t)
+ {
+ // Ignore everything and use original class.
+ }
+ }
+ else
+ {
+ // If we are not on JDK 1.5, try to figure out enclosing class.
+ int idx = clazz.getName().lastIndexOf('$');
+ if (idx > 0)
+ {
+ ClassLoader cl = clazz.getClassLoader() != null ? clazz.getClassLoader() : ClassLoader.getSystemClassLoader();
+ try
+ {
+ Class enclosing = cl.loadClass(clazz.getName().substring(0, idx));
+ clazz = (enclosing != null) ? enclosing : clazz;
+ }
+ catch (Throwable t)
+ {
+ // Ignore all problems since we are trying to load a class
+ // inside the class loader and this can lead to
+ // ClassCircularityError, for example.
+ }
+ }
+ }
+ return clazz;
+ }
+
private boolean shouldBootDelegate(String pkgName)
{
boolean result = false;