Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2019-08-07 22:04:53 +0000
committerThomas Watson2019-08-08 16:44:17 +0000
commit3f538fe8c4491fe9faa78c388385fec5aba3eb54 (patch)
tree5e320f44be197083a7c7e1f6b5198d945a6d47b9
parentd43eec5b6f7b407ba7ae5e83222d546234b196c1 (diff)
downloadrt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.tar.gz
rt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.tar.xz
rt.equinox.framework-3f538fe8c4491fe9faa78c388385fec5aba3eb54.zip
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>
-rw-r--r--bundles/org.eclipse.osgi.tests/.classpath1
-rw-r--r--bundles/org.eclipse.osgi.tests/build.properties3
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/META-INF/MANIFEST.MF5
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/test.protocol.handler.user/test/protocol/handler/user/Activator.java21
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AbstractFrameworkHookTests.java21
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/AllFrameworkHookTests.java1
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/hooks/framework/EmbeddedEquinoxWithURLInClassLoadTests.java68
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/url/MultiplexingFactory.java49
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)) {

Back to the top