Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2016-06-02 21:19:23 +0000
committerThomas Watson2016-06-03 13:36:12 +0000
commit9a6165fbb48f1c583c967e6debb1d23250b4fd29 (patch)
treeba760cc2558fda92b017d0137a6b1c173185d230
parentf355e41034d9d0a2969dc9331f910da7a7e8d565 (diff)
downloadrt.equinox.framework-R4_6.tar.gz
rt.equinox.framework-R4_6.tar.xz
rt.equinox.framework-R4_6.zip
Bug 495333 - ContextFinder returns null from getResourcesR4_6I20160606-1100I20160603-1000
If there are no classes loaded from bundle class loaders on the stack then ContextFinder.getResources can return null. This fix ensures an empty enumeration is returned instead. Change-Id: I07fe25eeaf8d02ea92cbe130794cdd2a011ae481 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java82
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/TestService.java18
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/loader/BundleLoader.java15
3 files changed, 110 insertions, 5 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
index b4d6729ee..8f4d2b15b 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/ClassLoadingBundleTests.java
@@ -14,7 +14,11 @@ import java.io.*;
import java.lang.reflect.Method;
import java.net.*;
import java.util.*;
-import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.*;
+import javax.jws.WebService;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Service;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.osgi.tests.OSGiTestsActivator;
@@ -1672,7 +1676,7 @@ public class ClassLoadingBundleTests extends AbstractBundleTests {
ClassLoader contextFinder = getContext().getService(getContext().getServiceReferences(ClassLoader.class, "(equinox.classloader.type=contextClassLoader)").iterator().next());
// Using a resource we know is in java 8.
String resource = "META-INF/services/javax.print.PrintServiceLookup";
- URL systemURL = ClassLoader.getSystemClassLoader().getResource("META-INF/services/javax.print.PrintServiceLookup");
+ URL systemURL = ClassLoader.getSystemClassLoader().getResource(resource);
assertNotNull("Did not find a parent resource: " + resource, systemURL);
//should return the file defined in test bundle.
URL url = contextFinder.getResource(resource);
@@ -1684,6 +1688,80 @@ public class ClassLoadingBundleTests extends AbstractBundleTests {
assertEquals(url.toExternalForm(), urls.get(0).toExternalForm());
}
+ @WebService(endpointInterface = "org.eclipse.osgi.tests.bundles.TestService")
+ public static class TestServiceImpl implements TestService {
+
+ @Override
+ public String hello(final String name) {
+ return "Hello " + name;
+ }
+
+ }
+
+ /*
+ * This test depends on the behavior of the JVM Endpoint implementation to use
+ * the context class loader to try and find resources using an executor.
+ * This is important because it causes the thread stack to have NO classes
+ * loaded by a bundle class loader. This causes a condition that would
+ * make ContextFinder.getResources to return null
+ */
+ public void testContextFinderEmptyGetResources() throws Exception {
+ // get the context finder explicitly to test incase the thread context class loader has changed
+ ClassLoader contextFinder = getContext().getService(getContext().getServiceReferences(ClassLoader.class, "(equinox.classloader.type=contextClassLoader)").iterator().next());
+ ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(contextFinder);
+ ExecutorService pool = null;
+ try {
+ pool = Executors.newFixedThreadPool(3);
+
+ final String address = "http://localhost:8888/service";
+
+ final WebService annotation = TestService.class.getAnnotation(WebService.class);
+ final String namespaceURI = annotation.serviceName();
+ final String localPart = annotation.targetNamespace();
+ final QName serviceName = new QName(namespaceURI, localPart);
+
+ final TestServiceImpl tsi = new TestServiceImpl();
+ final Endpoint endpoint = Endpoint.create(tsi);
+ final HashMap<String, Object> props = new HashMap<String, Object>();
+ props.put(Endpoint.WSDL_SERVICE, serviceName);
+
+ endpoint.setProperties(props);
+ endpoint.setExecutor(pool);
+ endpoint.publish(address);
+ final URL wsdlURL = new URL(address + "?wsdl");
+ final Service s = Service.create(wsdlURL, serviceName);
+ assertNotNull("Service is null.", s);
+ final TestService port = s.getPort(TestService.class);
+
+ assertEquals("Wrong result.", "Hello World", port.hello("World"));
+ } finally {
+ Thread.currentThread().setContextClassLoader(previousTCCL);
+ if (pool != null) {
+ pool.shutdown();
+ }
+ }
+ }
+
+ public void testBundleClassLoaderEmptyGetResources() throws Exception {
+ final ClassLoader bundleClassLoader = getClass().getClassLoader();
+ // Using a resource we know does not exist
+ final String resource = "META-INF/services/test.does.note.ExistService";
+ doTestEmptyGetResources(bundleClassLoader, resource);
+ }
+
+ private void doTestEmptyGetResources(ClassLoader testClassLoader, String resource) throws Exception {
+ URL systemURL = ClassLoader.getSystemClassLoader().getResource(resource);
+ assertNull("Found a parent resource: " + resource, systemURL);
+ // Should return null resource
+ URL testurl = testClassLoader.getResource(resource);
+ assertNull("Found a resource: " + resource, testurl);
+
+ Enumeration<URL> testResources = testClassLoader.getResources(resource);
+ assertNotNull("null resources from testClassLoader: " + resource, testResources);
+ assertFalse("Resources has elements.", testResources.hasMoreElements());
+ }
+
public void testBundleReference01() throws Exception {
Bundle test = installer.installBundle("test"); //$NON-NLS-1$
Class clazz = test.loadClass("test1.Activator"); //$NON-NLS-1$
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/TestService.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/TestService.java
new file mode 100644
index 000000000..c3d2ea34f
--- /dev/null
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/bundles/TestService.java
@@ -0,0 +1,18 @@
+/*******************************************************************************
+ * Copyright (c) 2016 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.tests.bundles;
+
+import javax.jws.WebService;
+
+@WebService(serviceName = "Foo", targetNamespace = "http://bar")
+public interface TestService {
+ String hello(String name);
+}
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 5fcfed8d1..2e7f0e319 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
@@ -64,6 +64,10 @@ public class BundleLoader extends ModuleLoader {
private static final Pattern PACKAGENAME_FILTER = Pattern.compile("\\(osgi.wiring.package\\s*=\\s*([^)]+)\\)"); //$NON-NLS-1$
+ // TODO needed instead of using Collections.emptyEnumertion until we no longer support Java 6
+ @SuppressWarnings("rawtypes")
+ private final static Enumeration EMPTY_ENUMERATION = Collections.enumeration(Collections.emptyList());
+
private final ModuleWiring wiring;
private final EquinoxContainer container;
private final Debug debug;
@@ -627,7 +631,7 @@ public class BundleLoader extends ModuleLoader {
if ((name.length() > 1) && (name.charAt(0) == '/')) /* if name has a leading slash */
name = name.substring(1); /* remove leading slash before search */
String pkgName = getResourcePackageName(name);
- Enumeration<URL> result = Collections.enumeration(Collections.<URL> emptyList());
+ Enumeration<URL> result = emptyEnumeration();
boolean bootDelegation = false;
// follow the OSGi delegation model
// First check the parent classloader for system resources, if it is a java resource.
@@ -781,9 +785,9 @@ public class BundleLoader extends ModuleLoader {
public static <E> Enumeration<E> compoundEnumerations(Enumeration<E> list1, Enumeration<E> list2) {
if (list2 == null || !list2.hasMoreElements())
- return list1;
+ return list1 == null ? BundleLoader.<E> emptyEnumeration() : list1;
if (list1 == null || !list1.hasMoreElements())
- return list2;
+ return list2 == null ? BundleLoader.<E> emptyEnumeration() : list2;
List<E> compoundResults = new ArrayList<E>();
while (list1.hasMoreElements())
compoundResults.add(list1.nextElement());
@@ -795,6 +799,11 @@ public class BundleLoader extends ModuleLoader {
return Collections.enumeration(compoundResults);
}
+ @SuppressWarnings("unchecked")
+ private static <E> Enumeration<E> emptyEnumeration() {
+ return EMPTY_ENUMERATION;
+ }
+
/**
* Finds a resource local to this bundle. Only the classloader for this bundle is searched.
* @param name The name of the resource to find.

Back to the top