Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-10-10 18:45:25 +0000
committerThomas Watson2019-10-14 14:56:11 +0000
commit4463a6cd56307985b0c0ddc66d3a94aa1cc46aff (patch)
tree7a4436a5c688eb301422a4dfc9c8861092a6c81c
parent97f9637d2c803b02e32f3cffe953c00457e63088 (diff)
downloadrt.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>
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/ContextFinder.java12
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainer.java19
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/framework/EquinoxContainerAdaptor.java24
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/PolicyHandler.java22
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/buddy/SystemPolicy.java13
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;
}

Back to the top