diff options
author | Thomas Watson | 2019-08-07 22:04:53 +0000 |
---|---|---|
committer | Thomas Watson | 2019-08-08 16:44:17 +0000 |
commit | 3f538fe8c4491fe9faa78c388385fec5aba3eb54 (patch) | |
tree | 5e320f44be197083a7c7e1f6b5198d945a6d47b9 | |
parent | d43eec5b6f7b407ba7ae5e83222d546234b196c1 (diff) | |
download | rt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.tar.gz rt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.tar.xz rt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.zip |
Bug 549895 - Ignore classes provided by the Java platformY20190812-0900I20190813-1800I20190812-1800I20190811-1800I20190810-1800I20190809-1800I20190808-1800
Should not ask the factories if they can handle classes provided by the
JRE because they cannot and it causes recursion to occur in cases where
a classloader loading the embedded framework itself creates URLs from
URI objects.
Change-Id: I1ca9b0a8690a4eb295b624ded73698b2dc7afd07
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
8 files changed, 160 insertions, 9 deletions
diff --git a/bundles/org.eclipse.osgi.tests/.classpath b/bundles/org.eclipse.osgi.tests/.classpath index 71ce99780..2650588cc 100644 --- a/bundles/org.eclipse.osgi.tests/.classpath +++ b/bundles/org.eclipse.osgi.tests/.classpath @@ -124,6 +124,7 @@ <classpathentry kind="src" output="bundle_tests/test.bug449484" path="bundles_src/test.bug449484"/> <classpathentry kind="src" output="bundle_tests/wrapper.hooks.a" path="bundles_src/wrapper.hooks.a"/> <classpathentry kind="src" output="bundle_tests/test.protocol.handler" path="bundles_src/test.protocol.handler"/> + <classpathentry kind="src" output="bundle_tests/test.protocol.handler.user" path="bundles_src/test.protocol.handler.user"/> <classpathentry kind="src" output="bundle_tests/test.bug471551" path="bundles_src/test.bug471551"/> <classpathentry kind="src" output="bundle_tests/test.dynamicimport" path="bundles_src/test.dynamicimport"/> <classpathentry kind="src" output="bundle_tests/test.bug490902.a" path="bundles_src/test.bug490902.a"/> diff --git a/bundles/org.eclipse.osgi.tests/build.properties b/bundles/org.eclipse.osgi.tests/build.properties index ad43e4ea0..b5f9ec757 100644 --- a/bundles/org.eclipse.osgi.tests/build.properties +++ b/bundles/org.eclipse.osgi.tests/build.properties @@ -263,6 +263,8 @@ source.bundle_tests/wrapper.hooks.a.jar = bundles_src/wrapper.hooks.a/ manifest.bundle_tests/wrapper.hooks.a.jar = META-INF/MANIFEST.MF source.bundle_tests/test.protocol.handler.jar = bundles_src/test.protocol.handler/ manifest.bundle_tests/test.protocol.handler.jar = META-INF/MANIFEST.MF +source.bundle_tests/test.protocol.handler.user.jar = bundles_src/test.protocol.handler.user/ +manifest.bundle_tests/test.protocol.handler.user.jar = META-INF/MANIFEST.MF source.bundle_tests/test.bug471551.jar = bundles_src/test.bug471551/ manifest.bundle_tests/test.bug471551.jar = META-INF/MANIFEST.MF source.bundle_tests/test.dynamicimport.jar = bundles_src/test.dynamicimport/ @@ -403,6 +405,7 @@ jars.compile.order = bundle_tests/ext.framework.b.jar,\ bundle_tests/test.bug449484.jar,\ bundle_tests/wrapper.hooks.a.jar,\ bundle_tests/test.protocol.handler.jar,\ + bundle_tests/test.protocol.handler.user.jar,\ bundle_tests/test.bug471551.jar,\ bundle_tests/test.dynamicimport.jar,\ bundle_tests/test.bug490902.b.jar,\ diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/META-INF/MANIFEST.MF new file mode 100644 index 000000000..2e05daf2c --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: test.protocol.handler.user +Bundle-Activator: test.protocol.handler.user.Activator +Import-Package: org.osgi.framework diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/test/protocol/handler/user/Activator.java b/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/test/protocol/handler/user/Activator.java new file mode 100644 index 000000000..fef905eca --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/test/protocol/handler/user/Activator.java @@ -0,0 +1,21 @@ +package test.protocol.handler.user; + +import java.net.URL; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + @Override + public void start(BundleContext context) throws Exception { + URL testURL = new URL("testing1://test"); + testURL.openConnection(); + System.out.println(testURL); + } + + @Override + public void stop(BundleContext context) throws Exception { + // nothing + } + +} diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java index cdbaa3fc8..f7726f3ee 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java @@ -14,6 +14,9 @@ package org.eclipse.osgi.tests.hooks.framework; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; @@ -31,8 +34,11 @@ import org.osgi.framework.launch.FrameworkFactory; public abstract class AbstractFrameworkHookTests extends CoreTest { protected static class BasicURLClassLoader extends URLClassLoader { - public BasicURLClassLoader(URL[] urls, ClassLoader parent) { + private volatile String testURL; + + public BasicURLClassLoader(URL[] urls, ClassLoader parent, String testURL) { super(urls, parent); + this.testURL = testURL; } @Override @@ -56,6 +62,16 @@ public abstract class AbstractFrameworkHookTests extends CoreTest { @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (testURL != null) { + try { + URL fileUrl = new URI(testURL).toURL(); + fileUrl.toString(); + } catch (MalformedURLException | URISyntaxException e) { + // stop doing the URI creating + testURL = null; + throw new RuntimeException(e); + } + } if (name.startsWith("org.eclipse") || name.startsWith("org.osgi.framework.FrameworkUtil")) { Class<?> result = findLoadedClass(name); if (result == null) @@ -73,6 +89,7 @@ public abstract class AbstractFrameworkHookTests extends CoreTest { protected static final String BUNDLES_ROOT = "bundle_tests"; protected BasicURLClassLoader classLoader; + protected String testURL = null; protected BundleInstaller bundleInstaller; public BundleContext getContext() { @@ -154,6 +171,6 @@ public abstract class AbstractFrameworkHookTests extends CoreTest { urls = new URL[] {new URL(osgiFramework), new URL(osgiFramework + "bin/")}; else urls = new URL[] {new URL(osgiFramework)}; - classLoader = new BasicURLClassLoader(urls, getClass().getClassLoader()); + classLoader = new BasicURLClassLoader(urls, getClass().getClassLoader(), testURL); } } diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java index 53880a53c..d86f3efd9 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java @@ -24,6 +24,7 @@ public class AllFrameworkHookTests { suite.addTest(new TestSuite(BundleFileWrapperFactoryHookTests.class)); suite.addTest(new TestSuite(ContextFinderTests.class)); suite.addTest(new TestSuite(DevClassPathWithExtensionTests.class)); + suite.addTest(new TestSuite(EmbeddedEquinoxWithURLInClassLoadTests.class)); return suite; } } diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/EmbeddedEquinoxWithURLInClassLoadTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/EmbeddedEquinoxWithURLInClassLoadTests.java new file mode 100644 index 000000000..c7c1c8ca8 --- /dev/null +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/EmbeddedEquinoxWithURLInClassLoadTests.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2013, 2018 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.tests.hooks.framework; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.osgi.tests.OSGiTestsActivator; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; +import org.osgi.framework.launch.Framework; + +public class EmbeddedEquinoxWithURLInClassLoadTests extends AbstractFrameworkHookTests { + + private Framework framework; + + @Override + protected void setUp() throws Exception { + URL myManifest = getClass().getResource("/META-INF/MANIFEST.MF"); + testURL = myManifest.toExternalForm(); + super.setUp(); + File file = OSGiTestsActivator.getContext().getDataFile(getName()); + Map<String, String> configuration = new HashMap<String, String>(); + configuration.put(Constants.FRAMEWORK_STORAGE, file.getAbsolutePath()); + framework = createFramework(configuration); + } + + @Override + protected void tearDown() throws Exception { + stopQuietly(framework); + super.tearDown(); + } + + private void initAndStartFramework() throws Exception { + initAndStart(framework); + } + + public void testFrameworkClassLoaderWithNewURI() throws Exception { + initAndStartFramework(); + } + + public void testEmbeddedURLHandler() throws Exception { + initAndStart(framework); + Bundle testHandler = framework.getBundleContext().installBundle(bundleInstaller.getBundleLocation("test.protocol.handler")); + testHandler.start(); + Bundle testHandlerUser = framework.getBundleContext().installBundle(bundleInstaller.getBundleLocation("test.protocol.handler.user")); + testHandlerUser.start(); + try { + URL testingURL = new URL("testing1://test"); + fail("Should not find testing1 protocol: " + testingURL); + } catch (MalformedURLException e) { + // expected + } + } +} diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/url/MultiplexingFactory.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/url/MultiplexingFactory.java index 0d4e0b298..5d9ced4b3 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/url/MultiplexingFactory.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/url/MultiplexingFactory.java @@ -11,14 +11,24 @@ *******************************************************************************/ package org.eclipse.osgi.internal.url; -import java.lang.reflect.*; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.net.URL; -import java.util.*; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import org.eclipse.osgi.framework.log.FrameworkLogEntry; import org.eclipse.osgi.internal.framework.EquinoxBundle; import org.eclipse.osgi.internal.framework.EquinoxContainer; import org.eclipse.osgi.storage.StorageUtil; -import org.osgi.framework.*; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; /* * An abstract class for handler factory impls (Stream and Content) that can @@ -40,6 +50,7 @@ public abstract class MultiplexingFactory { * it the ability to call setAccessible(true) on other types from the java.base module */ static final Collection<AccessibleObject> setAccessible; + static final Collection<ClassLoader> systemLoaders; static { Collection<AccessibleObject> result = null; try { @@ -64,6 +75,18 @@ public abstract class MultiplexingFactory { // ingore as if there is no Unsafe } setAccessible = result; + + Collection<ClassLoader> loaders = new ArrayList<>(); + try { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + while (cl != null) { + loaders.add(cl); + cl = cl.getParent(); + } + } catch (Throwable t) { + // ignore as if no loaders + } + systemLoaders = Collections.unmodifiableCollection(loaders); } protected EquinoxContainer container; protected BundleContext context; @@ -101,7 +124,8 @@ public abstract class MultiplexingFactory { setParentFactory.invoke(factory, new Object[] {getParentFactory()}); } catch (Exception e) { container.getLogServices().log(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, "register", e); //$NON-NLS-1$ - throw new RuntimeException(e.getMessage(), e); + // just return and not have it registered + return; } addFactory(factory); } @@ -116,7 +140,7 @@ public abstract class MultiplexingFactory { closeTracker.invoke(factory, (Object[]) null); } catch (Exception e) { container.getLogServices().log(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, "unregister", e); //$NON-NLS-1$ - throw new RuntimeException(e.getMessage(), e); + // just return without blowing up here } } @@ -155,7 +179,7 @@ public abstract class MultiplexingFactory { List<Object> current = getFactories(); Class<?>[] classStack = internalSecurityManager.getClassContext(); for (Class<?> clazz : classStack) { - if (clazz == InternalSecurityManager.class || clazz == MultiplexingFactory.class || ignoredClasses.contains(clazz)) + if (clazz == InternalSecurityManager.class || clazz == MultiplexingFactory.class || ignoredClasses.contains(clazz) || isSystemClass(clazz)) continue; if (hasAuthority(clazz)) return this; @@ -169,7 +193,7 @@ public abstract class MultiplexingFactory { } } catch (Exception e) { container.getLogServices().log(MultiplexingFactory.class.getName(), FrameworkLogEntry.ERROR, "findAuthorizedURLStreamHandler-loop", e); //$NON-NLS-1$ - throw new RuntimeException(e.getMessage(), e); + // we continue to the next factory here instead of failing } } } @@ -179,6 +203,17 @@ public abstract class MultiplexingFactory { return this; } + private boolean isSystemClass(final Class<?> clazz) { + // we want to ignore classes from the system + ClassLoader cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + @Override + public ClassLoader run() { + return clazz.getClassLoader(); + } + }); + return cl == null || systemLoaders.contains(cl); + } + public boolean hasAuthority(Class<?> clazz) { Bundle b = FrameworkUtil.getBundle(clazz); if (!(b instanceof EquinoxBundle)) { |