Class loader used for boot delegation is now configurable,
per R4.2 launching and embedding API. (FELIX-1193)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@789939 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
index 4abf8be..115335b 100644
--- a/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ModuleImpl.java
@@ -96,6 +96,26 @@
private boolean m_isActivationTriggered = false;
private ProtectionDomain m_protectionDomain = null;
private static SecureAction m_secureAction = new SecureAction();
+ // Class load to be used for boot delegation.
+ private final static ClassLoader m_bootClassLoader;
+ // Statically create the class loader for boot delegation.
+ static
+ {
+ try
+ {
+ ClassLoader cl = null;
+ Constructor ctor = m_secureAction.getDeclaredConstructor(
+ SecureClassLoader.class, new Class[] { ClassLoader.class });
+ m_secureAction.setAccesssible(ctor);
+ cl = (ClassLoader) m_secureAction.invoke(ctor, new Object[] { null });
+ m_bootClassLoader = cl;
+ }
+ catch (Exception ex)
+ {
+ throw new RuntimeException(
+ "Problem creating boot delegation class loader.", ex);
+ }
+ }
// Boot delegation packages.
private final String[] m_bootPkgs;
@@ -596,6 +616,15 @@
{
try
{
+ // Get the appropriate class loader for delegation.
+ ClassLoader parent = m_classLoader.getParent();
+ parent = (parent == null) ? m_bootClassLoader : parent;
+ result = (isClass)
+ ? (Object) parent.loadClass(name)
+ : (Object) parent.getResource(name);
+ // If this is a java.* package, then always terminate the
+ // search; otherwise, continue to look locally if not found.
+ if (pkgName.startsWith("java.") || (result != null))
result = (isClass)
? (Object) getClass().getClassLoader().loadClass(name)
: (Object) getClass().getClassLoader().getResource(name);
@@ -777,7 +806,10 @@
{
try
{
- urls = getClass().getClassLoader().getResources(name);
+ // Get the appropriate class loader for delegation.
+ ClassLoader parent = m_classLoader.getParent();
+ parent = (parent == null) ? m_bootClassLoader : parent;
+ urls = parent.getResources(name);
}
catch (IOException ex)
{
@@ -1233,13 +1265,36 @@
{
if (m_classLoader == null)
{
+ // Determine the class loader's parent based on the
+ // configuration property; use boot class loader by
+ // default.
+ String cfg = (String) m_configMap.get(Constants.FRAMEWORK_BUNDLE_PARENT);
+ cfg = (cfg == null) ? Constants.FRAMEWORK_BUNDLE_PARENT_BOOT : cfg;
+ final ClassLoader parent;
+ if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_APP))
+ {
+ parent = ClassLoader.getSystemClassLoader();
+ }
+ else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_EXT))
+ {
+ parent = ClassLoader.getSystemClassLoader().getParent();
+ }
+ else if (cfg.equalsIgnoreCase(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK))
+ {
+ parent = ModuleImpl.class.getClassLoader();
+ }
+ else
+ {
+ parent = null;
+ }
if (System.getSecurityManager() != null)
{
try
{
Constructor ctor = (Constructor) m_secureAction.getConstructor(
- ModuleClassLoader.class, null);
- m_classLoader = (ModuleClassLoader) m_secureAction.invoke(ctor, null);
+ ModuleClassLoader.class, new Class[] { ClassLoader.class });
+ m_classLoader = (ModuleClassLoader)
+ m_secureAction.invoke(ctor, new Object[] { parent });
}
catch (Exception ex)
{
@@ -1248,7 +1303,7 @@
}
else
{
- m_classLoader = new ModuleClassLoader();
+ m_classLoader = new ModuleClassLoader(parent);
}
}
return m_classLoader;
@@ -1505,8 +1560,9 @@
{
private final Map m_jarContentToDexFile;
- public ModuleClassLoader()
+ public ModuleClassLoader(ClassLoader parent)
{
+ super(parent);
if (m_dexFileClassLoadClass != null)
{
m_jarContentToDexFile = new HashMap();