diff options
author | Thomas Watson | 2019-10-10 18:45:25 +0000 |
---|---|---|
committer | Thomas Watson | 2019-10-14 14:56:11 +0000 |
commit | 4463a6cd56307985b0c0ddc66d3a94aa1cc46aff (patch) | |
tree | 7a4436a5c688eb301422a4dfc9c8861092a6c81c | |
parent | 97f9637d2c803b02e32f3cffe953c00457e63088 (diff) | |
download | rt.equinox.framework-4463a6cd56307985b0c0ddc66d3a94aa1cc46aff.tar.gz rt.equinox.framework-4463a6cd56307985b0c0ddc66d3a94aa1cc46aff.tar.xz rt.equinox.framework-4463a6cd56307985b0c0ddc66d3a94aa1cc46aff.zip |
Bug 552087 - Avoid creating class loaders in static initializers
This becomes problematic when trying to create a
substrate VM native image. We can easily avoid this
but finding the boot loader in the constructor of
EquionoxContainer
Change-Id: Ibfcf974de69772cf585a4495d4d2fa0903dcf7a3
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
6 files changed, 54 insertions, 38 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java index aece758f9..0c3cf1ef5 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java @@ -17,7 +17,13 @@ import java.io.IOException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; import org.eclipse.osgi.internal.loader.BundleLoader; import org.eclipse.osgi.internal.loader.ModuleClassLoader; @@ -49,9 +55,9 @@ public class ContextFinder extends ClassLoader implements PrivilegedAction<List< private final ClassLoader parentContextClassLoader; - public ContextFinder(ClassLoader contextClassLoader) { + public ContextFinder(ClassLoader contextClassLoader, ClassLoader bootLoader) { super(contextClassLoader); - this.parentContextClassLoader = contextClassLoader != null ? contextClassLoader : EquinoxContainerAdaptor.BOOT_CLASSLOADER; + this.parentContextClassLoader = contextClassLoader != null ? contextClassLoader : bootLoader; } // Return a list of all classloaders on the stack that are neither the diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java index ce690f667..d728c9fa9 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java @@ -14,6 +14,7 @@ package org.eclipse.osgi.internal.framework; import java.io.IOException; +import java.lang.reflect.Method; import java.security.AccessController; import java.util.ArrayList; import java.util.HashSet; @@ -65,6 +66,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable { private final Object monitor = new Object(); + private final ClassLoader bootLoader; private ServiceRegistry serviceRegistry; private ContextFinder contextFinder; @@ -74,6 +76,16 @@ public class EquinoxContainer implements ThreadFactory, Runnable { private StorageSaver storageSaver; public EquinoxContainer(Map<String, ?> configuration) { + ClassLoader platformClassLoader = null; + try { + Method getPlatformClassLoader = ClassLoader.class.getMethod("getPlatformClassLoader"); //$NON-NLS-1$ + platformClassLoader = (ClassLoader) getPlatformClassLoader.invoke(null); + } catch (Throwable t) { + // try everything possible to not fail + platformClassLoader = new ClassLoader(Object.class.getClassLoader()) { + /* boot class loader */}; + } + this.bootLoader = platformClassLoader; this.equinoxConfig = new EquinoxConfiguration(configuration, new HookRegistry(this)); this.logServices = new EquinoxLogServices(this.equinoxConfig); this.equinoxConfig.logMessages(this.logServices); @@ -210,7 +222,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable { if (EquinoxConfiguration.CONTEXTCLASSLOADER_PARENT_APP.equals(type)) parent = ClassLoader.getSystemClassLoader(); else if (EquinoxConfiguration.CONTEXTCLASSLOADER_PARENT_BOOT.equals(type)) - parent = EquinoxContainerAdaptor.BOOT_CLASSLOADER; + parent = bootLoader; else if (EquinoxConfiguration.CONTEXTCLASSLOADER_PARENT_FWK.equals(type)) parent = EquinoxContainer.class.getClassLoader(); else if (EquinoxConfiguration.CONTEXTCLASSLOADER_PARENT_EXT.equals(type)) { @@ -220,7 +232,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable { } else { // default is ccl (null or any other value will use ccl) parent = current.getContextClassLoader(); } - contextFinder = new ContextFinder(parent); + contextFinder = new ContextFinder(parent, bootLoader); current.setContextClassLoader(contextFinder); return; } catch (Exception e) { @@ -316,4 +328,7 @@ public class EquinoxContainer implements ThreadFactory, Runnable { // Do nothing; just used to ensure the active thread is created during init } + public ClassLoader getBootLoader() { + return bootLoader; + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java index 248a8b6bc..ace518c87 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java @@ -13,7 +13,6 @@ *******************************************************************************/ package org.eclipse.osgi.internal.framework; -import java.lang.reflect.Method; import java.security.ProtectionDomain; import java.util.EnumSet; import java.util.List; @@ -57,19 +56,6 @@ import org.osgi.framework.hooks.resolver.ResolverHookFactory; import org.osgi.framework.wiring.BundleRevision; public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { - public static final ClassLoader BOOT_CLASSLOADER; - static { - ClassLoader platformClassLoader = null; - try { - Method getPlatformClassLoader = ClassLoader.class.getMethod("getPlatformClassLoader"); //$NON-NLS-1$ - platformClassLoader = (ClassLoader) getPlatformClassLoader.invoke(null); - } catch (Throwable t) { - // try everything possible to not fail <clinit> - platformClassLoader = new ClassLoader(Object.class.getClassLoader()) { - /* boot class loader */}; - } - BOOT_CLASSLOADER = platformClassLoader; - } private final EquinoxContainer container; private final Storage storage; private final OSGiFrameworkHooks hooks; @@ -88,7 +74,7 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { this.storage = storage; this.hooks = new OSGiFrameworkHooks(container, storage); this.initial = initial; - this.moduleClassLoaderParent = getModuleClassLoaderParent(container.getConfiguration()); + this.moduleClassLoaderParent = getModuleClassLoaderParent(container.getConfiguration(), container.getBootLoader()); this.lastSecurityAdminFlush = new AtomicLong(); EquinoxConfiguration config = container.getConfiguration(); @@ -174,7 +160,7 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { }; } - private static ClassLoader getModuleClassLoaderParent(EquinoxConfiguration configuration) { + private static ClassLoader getModuleClassLoaderParent(EquinoxConfiguration configuration, ClassLoader bootLoader) { // allow hooks to determine the parent class loader for (ClassLoaderHook hook : configuration.getHookRegistry().getClassLoaderHooks()) { ClassLoader parent = hook.getModuleClassLoaderParent(configuration); @@ -193,7 +179,7 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { if (Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK.equalsIgnoreCase(type) || EquinoxConfiguration.PARENT_CLASSLOADER_FWK.equalsIgnoreCase(type)) { ClassLoader cl = EquinoxContainer.class.getClassLoader(); - return cl == null ? BOOT_CLASSLOADER : cl; + return cl == null ? bootLoader : cl; } if (Constants.FRAMEWORK_BUNDLE_PARENT_APP.equalsIgnoreCase(type)) return ClassLoader.getSystemClassLoader(); @@ -202,7 +188,7 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { if (appCL != null) return appCL.getParent(); } - return BOOT_CLASSLOADER; + return bootLoader; } @@ -252,7 +238,7 @@ public class EquinoxContainerAdaptor extends ModuleContainerAdaptor { public ModuleLoader createModuleLoader(ModuleWiring wiring) { if (wiring.getBundle().getBundleId() == 0) { ClassLoader cl = EquinoxContainer.class.getClassLoader(); - cl = cl == null ? BOOT_CLASSLOADER : cl; + cl = cl == null ? container.getBootLoader() : cl; return new SystemBundleLoader(wiring, container, cl); } if ((wiring.getRevision().getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java index a2cc76ffd..9bc6370e8 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java @@ -189,7 +189,7 @@ public class BundleLoader extends ModuleLoader { List<ModuleCapability> moduleDatas = wiring.getRevision().getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE); @SuppressWarnings("unchecked") List<String> buddyList = (List<String>) (moduleDatas.isEmpty() ? null : moduleDatas.get(0).getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_BUDDY_POLICY)); - policy = buddyList != null ? new PolicyHandler(this, buddyList, container.getPackageAdmin()) : null; + policy = buddyList != null ? new PolicyHandler(this, buddyList, container.getPackageAdmin(), container.getBootLoader()) : null; if (policy != null) { Module systemModule = container.getStorage().getModuleContainer().getModule(0); Bundle systemBundle = systemModule.getBundle(); diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java index 462e61939..16285449d 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java @@ -14,11 +14,19 @@ package org.eclipse.osgi.internal.loader.buddy; import java.net.URL; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent; import org.eclipse.osgi.internal.framework.EquinoxBundle; import org.eclipse.osgi.internal.loader.BundleLoader; -import org.osgi.framework.*; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.SynchronousBundleListener; import org.osgi.service.packageadmin.PackageAdmin; public class PolicyHandler implements SynchronousBundleListener { @@ -40,13 +48,15 @@ public class PolicyHandler implements SynchronousBundleListener { //Support to cut class / resource loading cycles in the context of one thread. The contained object is a set of classname private final ThreadLocal<Set<String>> beingLoaded; private final PackageAdmin packageAdmin; + private final ClassLoader bootLoader; - public PolicyHandler(BundleLoader loader, List<String> buddyList, PackageAdmin packageAdmin) { + public PolicyHandler(BundleLoader loader, List<String> buddyList, PackageAdmin packageAdmin, ClassLoader bootLoader) { policedLoader = loader; this.originalBuddyList = buddyList; policies = buddyList.toArray(); beingLoaded = new ThreadLocal<>(); this.packageAdmin = packageAdmin; + this.bootLoader = bootLoader; } static Object[] getArrayFromList(String stringList) { @@ -74,15 +84,15 @@ public class PolicyHandler implements SynchronousBundleListener { return (IBuddyPolicy) policiesSnapshot[policyOrder]; } if (BOOT_POLICY.equals(buddyName)) { - policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.BOOT); + policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.BOOT, bootLoader); return (IBuddyPolicy) policiesSnapshot[policyOrder]; } if (APP_POLICY.equals(buddyName)) { - policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.APP); + policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.APP, bootLoader); return (IBuddyPolicy) policiesSnapshot[policyOrder]; } if (EXT_POLICY.equals(buddyName)) { - policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.EXT); + policiesSnapshot[policyOrder] = SystemPolicy.getInstance(SystemPolicy.EXT, bootLoader); return (IBuddyPolicy) policiesSnapshot[policyOrder]; } if (DEPENDENT_POLICY.equals(buddyName)) { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/SystemPolicy.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/SystemPolicy.java index 6b471d4b1..9c5eb813f 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/SystemPolicy.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/SystemPolicy.java @@ -18,7 +18,6 @@ import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Enumeration; -import org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor; public class SystemPolicy implements IBuddyPolicy { @@ -30,13 +29,13 @@ public class SystemPolicy implements IBuddyPolicy { private ClassLoader classLoader; - public static SystemPolicy getInstance(final byte type) { + public static SystemPolicy getInstance(final byte type, final ClassLoader bootLoader) { if (instances[type] == null) { instances[type] = new SystemPolicy(); instances[type].classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { @Override public ClassLoader run() { - return createClassLoader(type); + return createClassLoader(type, bootLoader); } }); } @@ -51,20 +50,20 @@ public class SystemPolicy implements IBuddyPolicy { classLoader = parent; } - static ClassLoader createClassLoader(byte type) { + static ClassLoader createClassLoader(byte type, ClassLoader bootLoader) { switch (type) { case APP : if (ClassLoader.getSystemClassLoader() != null) return ClassLoader.getSystemClassLoader(); - return EquinoxContainerAdaptor.BOOT_CLASSLOADER; + return bootLoader; case BOOT : - return EquinoxContainerAdaptor.BOOT_CLASSLOADER; + return bootLoader; case EXT : if (ClassLoader.getSystemClassLoader() != null) return ClassLoader.getSystemClassLoader().getParent(); - return EquinoxContainerAdaptor.BOOT_CLASSLOADER; + return bootLoader; } return null; } |