Author: rmannibucau Date: Mon Apr 29 13:08:27 2013 New Revision: 1477030 URL: http://svn.apache.org/r1477030 Log: TOMEE-921 allow cxf client to use app classes
Modified: tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java Modified: tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java?rev=1477030&r1=1477029&r2=1477030&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfContainerClassLoader.java Mon Apr 29 13:08:27 2013 @@ -40,10 +40,22 @@ public class CxfContainerClassLoader ext tccl.remove(); } + public boolean hasTccl() { + final ClassLoader current = tccl.get(); + if (current != null) { + return true; + } + + tccl.remove(); + return false; + } + private ClassLoader tccl() { final ClassLoader current = tccl.get(); if (current != null) { return current; + } else { + tccl.remove(); } return CONTAINER_LOADER; } Modified: tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java?rev=1477030&r1=1477029&r2=1477030&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-transport/src/main/java/org/apache/openejb/server/cxf/transport/util/CxfUtil.java Mon Apr 29 13:08:27 2013 @@ -22,7 +22,6 @@ import org.apache.cxf.binding.BindingFac import org.apache.cxf.binding.BindingFactoryManager; import org.apache.cxf.bus.CXFBusFactory; import org.apache.cxf.bus.CXFBusImpl; -import org.apache.cxf.bus.extension.ExtensionManagerBus; import org.apache.cxf.bus.managers.BindingFactoryManagerImpl; import org.apache.cxf.configuration.spring.MapProvider; import org.apache.cxf.databinding.DataBinding; @@ -39,6 +38,9 @@ import org.apache.openejb.assembler.clas import org.apache.openejb.loader.SystemInstance; import org.apache.openejb.util.PropertiesHelper; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.util.Collection; import java.util.List; import java.util.Map; @@ -57,10 +59,9 @@ public final class CxfUtil { public static final String DEBUG = "debug"; public static final String BUS_PREFIX = "org.apache.openejb.cxf.bus."; public static final String BUS_CONFIGURED_FLAG = "openejb.cxf.bus.configured"; - - private static volatile boolean usingBindingFactoryMap = false; private static final Map<String, BindingFactory> bindingFactoryMap = new ConcurrentHashMap<String, BindingFactory>(8, 0.75f, 4); private static final Bus DEFAULT_BUS = initDefaultBus(); // has to be initializd after bindingFactoryMap + private static volatile boolean usingBindingFactoryMap = false; private CxfUtil() { // no-op @@ -87,7 +88,10 @@ public final class CxfUtil { }); } - return bus; + // ensure client proxies can use app classes + CXFBusFactory.setDefaultBus(Bus.class.cast(Proxy.newProxyInstance(CxfUtil.class.getClassLoader(), new Class<?>[]{ Bus.class }, new ClientAwareBusHandler()))); + + return bus; // we keep as internal the real bus and just expose to cxf the client aware bus to be able to cast it easily } finally { Thread.currentThread().setContextClassLoader(cl); } @@ -251,4 +255,24 @@ public final class CxfUtil { SystemInstance.get().getProperties().setProperty(BUS_CONFIGURED_FLAG, "true"); } } + + private static class ClientAwareBusHandler implements InvocationHandler { + @Override + public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { + final Bus bus = getBus(); + + // when creating a client it is important to use the application loader to be able to load application classes + // it is the default case but using our own CxfClassLoader we make it wrong so simply skip it when calling a client + // and no app classloader is registered + if ("getExtension".equals(method.getName()) && args != null && args.length == 1 && ClassLoader.class.equals(args[0])) { + final ClassLoader extensionLoader = ClassLoader.class.cast(method.invoke(bus, args)); + if (CxfContainerClassLoader.class.isInstance(extensionLoader) && !CxfContainerClassLoader.class.cast(extensionLoader).hasTccl()) { + return null; + } + return extensionLoader; + } + + return method.invoke(bus, args); + } + } }