diff options
author | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-09 01:08:37 +0000 |
---|---|---|
committer | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-08-09 01:08:37 +0000 |
commit | d00035085d6089d942ff3179556e8893e2790b23 (patch) | |
tree | d64185218ef9f3a86f73ee471df99a4e564a2d8a | |
parent | d927ce193627f96cac6b6d7dd83506b5fab1a585 (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
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; + } + } } |