summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-08-09 01:08:37 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2009-08-09 01:08:37 +0000
commitd00035085d6089d942ff3179556e8893e2790b23 (patch)
treed64185218ef9f3a86f73ee471df99a4e564a2d8a
parentd927ce193627f96cac6b6d7dd83506b5fab1a585 (diff)
Add a method to ServiceDiscovery to set context classloader for service providers in OSGi
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@802470 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java82
-rw-r--r--java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java22
-rw-r--r--java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java122
3 files changed, 131 insertions, 95 deletions
diff --git a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
index fcf8fa05d4..782cfd6066 100644
--- a/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
+++ b/java/sca/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ConfiguratorHelper.java
@@ -19,17 +19,9 @@
package org.apache.tuscany.sca.binding.ws.axis2;
-import java.io.IOException;
-import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Set;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.ConfigurationContext;
@@ -43,66 +35,6 @@ import org.oasisopen.sca.ServiceRuntimeException;
public class Axis2ConfiguratorHelper {
/**
- * This classloader is used in OSGi to work around XXXFactory.newInstance()
- */
- static class MultiParentClassLoader extends ClassLoader {
- private final Collection<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
-
- /**
- * @param parent The parent classloaders
- * @param loaders A list of classloaders to be used to load classes or resources
- */
- public MultiParentClassLoader(ClassLoader parent, ClassLoader[] loaders) {
- super(parent);
- if (loaders != null) {
- for (ClassLoader cl : loaders) {
- if (cl != null && cl != parent && !classLoaders.contains(cl)) {
- this.classLoaders.add(cl);
- }
- }
- }
- }
-
- @Override
- protected Class<?> findClass(String className) throws ClassNotFoundException {
- for (ClassLoader parent : classLoaders) {
- try {
- return parent.loadClass(className);
- } catch (ClassNotFoundException e) {
- continue;
- }
- }
- throw new ClassNotFoundException(className);
- }
-
- @Override
- protected URL findResource(String resName) {
- for (ClassLoader parent : classLoaders) {
- URL url = parent.getResource(resName);
- if (url != null) {
- return url;
- }
- }
- return null;
- }
-
- @Override
- protected Enumeration<URL> findResources(String resName) throws IOException {
- Set<URL> urlSet = new HashSet<URL>();
- for (ClassLoader parent : classLoaders) {
- Enumeration<URL> urls = parent.getResources(resName);
- if (urls != null) {
- while (urls.hasMoreElements()) {
- urlSet.add(urls.nextElement());
- }
- }
- }
- return Collections.enumeration(urlSet);
- }
- }
-
-
- /**
* We cannot hold this method directly in the {@link TuscanyAxisConfigurator} class as the super class
* uses the TCCL to load classes
*
@@ -124,20 +56,12 @@ public class Axis2ConfiguratorHelper {
// The axis2 class loader
ClassLoader cl1 = URLBasedAxisConfigurator.class.getClassLoader();
- // The extensibility class loader that sees all 3rd party jars
- ClassLoader cl2 = ServiceDiscovery.getInstance().getContextClassLoader();
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- ClassLoader newTccl = tccl;
- if (cl0 != tccl || cl1 != tccl || cl2 != tccl) {
- newTccl = new MultiParentClassLoader(null, new ClassLoader[] {cl0, cl1, cl2, tccl});
- }
- if (newTccl != null && newTccl != tccl) {
- Thread.currentThread().setContextClassLoader(newTccl);
- }
+ ClassLoader tccl = ServiceDiscovery.getInstance().setContextClassLoader(cl0, cl1);
+
try {
return new TuscanyAxisConfigurator(isRampartRequired).getConfigurationContext();
} finally {
- if (newTccl != null && newTccl != tccl) {
+ if (tccl != null) {
Thread.currentThread().setContextClassLoader(tccl);
}
}
diff --git a/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java b/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
index a8d99ad0dd..6b32f0844b 100644
--- a/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
+++ b/java/sca/modules/databinding-jaxb/src/main/java/org/apache/tuscany/sca/databinding/jaxb/JAXBContextCache.java
@@ -52,10 +52,10 @@ import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import javax.xml.datatype.DatatypeFactory;
import javax.xml.transform.Source;
import org.apache.tuscany.sca.databinding.util.LRUCache;
-import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
/**
@@ -124,25 +124,15 @@ public class JAXBContextCache {
return AccessController.doPrivileged(new PrivilegedExceptionAction<JAXBContext>() {
public JAXBContext run() throws JAXBException {
// Try to set up TCCL so that JAXBContext service discovery works in OSGi
- ClassLoader tccl = Thread.currentThread().getContextClassLoader();
- ClassLoader newTccl = tccl;
- try {
- ServiceDeclaration sd =
- ServiceDiscovery.getInstance().getServiceDeclaration(JAXBContext.class.getName());
- if (sd != null) {
- newTccl = sd.loadClass().getClassLoader();
- }
- } catch (Exception e) {
- // Ignore
- }
- if (newTccl != tccl) {
- Thread.currentThread().setContextClassLoader(newTccl);
- }
+ ClassLoader tccl =
+ ServiceDiscovery.getInstance().setContextClassLoader(JAXBContextCache.class.getClassLoader(),
+ JAXBContext.class.getName(),
+ DatatypeFactory.class.getName());
try {
JAXBContext context = JAXBContext.newInstance(classesToBeBound);
return context;
} finally {
- if (newTccl != tccl) {
+ if (tccl != null) {
Thread.currentThread().setContextClassLoader(tccl);
}
}
diff --git a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java
index 70274752e4..e92655146c 100644
--- a/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java
+++ b/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceDiscovery.java
@@ -20,12 +20,16 @@
package org.apache.tuscany.sca.extensibility;
import java.io.IOException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -185,5 +189,123 @@ public final class ServiceDiscovery implements ServiceDiscoverer {
public ClassLoader getContextClassLoader() {
return discoverer.getContextClassLoader();
}
+
+ private static class ClassLoaderDelegate extends ClassLoader {
+ private final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
+
+ /**
+ * @param parent The parent classloaders
+ * @param loaders A list of classloaders to be used to load classes or resources
+ */
+ public ClassLoaderDelegate(ClassLoader parent, Collection<ClassLoader> loaders) {
+ super(parent);
+ if (loaders != null) {
+ for (ClassLoader cl : loaders) {
+ if (cl != null && cl != parent && !classLoaders.contains(cl)) {
+ this.classLoaders.add(cl);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected Class<?> findClass(String className) throws ClassNotFoundException {
+ for (ClassLoader parent : classLoaders) {
+ try {
+ return parent.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+ }
+ throw new ClassNotFoundException(className);
+ }
+
+ @Override
+ protected URL findResource(String resName) {
+ for (ClassLoader parent : classLoaders) {
+ URL url = parent.getResource(resName);
+ if (url != null) {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ protected Enumeration<URL> findResources(String resName) throws IOException {
+ Set<URL> urlSet = new HashSet<URL>();
+ for (ClassLoader parent : classLoaders) {
+ Enumeration<URL> urls = parent.getResources(resName);
+ if (urls != null) {
+ while (urls.hasMoreElements()) {
+ urlSet.add(urls.nextElement());
+ }
+ }
+ }
+ return Collections.enumeration(urlSet);
+ }
+ }
+
+ private ClassLoader getClassLoader(String serviceProvider) {
+ try {
+ ServiceDeclaration sd = getServiceDeclaration(serviceProvider);
+ if (sd != null) {
+ return sd.loadClass().getClassLoader();
+ }
+ } catch (Exception e) {
+ // Ignore
+ }
+ return null;
+ }
+
+ /**
+ * Set the context classloader so that it can access the list of service providers
+ * @param parent The parent classloader
+ * @param serviceProviders A list of service provider names
+ * @return The old TCCL if a new one is set, otherwise null
+ */
+ public ClassLoader setContextClassLoader(ClassLoader parent, String... serviceProviders) {
+ List<ClassLoader> loaders = getClassLoaders(serviceProviders);
+ return setContextClassLoader(parent, loaders.toArray(new ClassLoader[loaders.size()]));
+ }
+
+ private List<ClassLoader> getClassLoaders(String... serviceProviders) {
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>();
+ for (String sp : serviceProviders) {
+ ClassLoader loader = getClassLoader(sp);
+ if (loader != null) {
+ if (!loaders.contains(loader)) {
+ loaders.add(loader);
+ }
+ }
+ }
+ return loaders;
+ }
+
+ public ClassLoader setContextClassLoader(ClassLoader parent, ClassLoader... delegates) {
+ ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ List<ClassLoader> loaders = new ArrayList<ClassLoader>();
+ for (ClassLoader loader : delegates) {
+ if (loader != null && loader != tccl && loader != parent) {
+ if (!loaders.contains(loader)) {
+ loaders.add(loader);
+ }
+ }
+ }
+ if (!loaders.isEmpty()) {
+ ClassLoader cl = getContextClassLoader();
+ if (cl != parent) {
+ loaders.add(cl);
+ }
+ if (tccl != parent) {
+ loaders.add(tccl);
+ }
+ ClassLoader newTccl = new ClassLoaderDelegate(parent, loaders);
+ Thread.currentThread().setContextClassLoader(newTccl);
+ return tccl;
+ } else {
+ return null;
+ }
+ }
}