That seems reasonable to me.   Feel free to apply it.


Dan


On Apr 2, 2014, at 8:00 AM, Alessio Soldano <[email protected]> wrote:

> Hi,
> I've started testing the JBossWS integration with Apache CXF 3 and I'm 
> currently dealing with a classloading issue on client side.
> A relevant difference between 2.7.x and 3 when it comes to JAXWS client 
> proxies is that on 3 they implement the org.apache.cxf.endpoint.Client 
> interface [1], while on 2.7.x they don't.
> When building up a JAXWS client, the org.apache.cxf.common.util.ProxyHelper 
> is used to decide which classloader will later be passed to the JDK Proxy for 
> building the proxy instance. If the classloader that loaded the user service 
> class has visibility over all the interfaces the proxy has to implement, that 
> classloader is used, otherwise a ProxyClassloader is built. The 
> ProxyClassloader is basically a combination of the classloaders that loaded 
> each specific interface class.
> Now, with Apache CXF 2.7.x, the user application needs to have visibility 
> over the JAX-WS api only, while with 3.0 it also needs to "see" the Apache 
> CXF classes, because of the check for org.apache.cxf.endpoint.Client 
> interface. When running JAX-WS applications on WildFly using the JBossWS 
> integration, the user is not *required* to set a dependency to Apache CXF 
> modules, even if they're internally used to serve JAX-WS functionalities. For 
> this reason, the service class classloader, which is a JBoss Module 
> classloader, won't usually allow loading the org.apache.cxf.endpoint.Client 
> *directly* (that is is by doing 
> Class.forName("org.apache.cxf.endpoint.Client", true, loader)). For this 
> reason, the ProxyHelper will go the combined classloader approach.
> The problem with such an approach on WildFly / JBoss AS is that later the JDK 
> Proxy will try to load the interfaces using the ProxyClassloader, whose 
> parent is the boot classloader. On recent JDK version, the boot classloader 
> is able to load the JAX-WS api classes (because they're included in the JDK); 
> however, the javax.xml.ws.BindinProvider interface class that was retrieved 
> from the service class is a different class, having been loaded by a specific 
> module part of the service class classloader. This makes a check fail in the 
> JDK Proxy, effectively preventing creating the jaxws client proxy.
> To me, the CXF ProxyClassloader should have an explicit parent classloader 
> set to the same classloader instance that was provided (the application 
> classloader, that is the service class classloader). That in turn *might* 
> have the boot classloader as parent (not in the case of JBoss / WildFly, due 
> to the modular approach).
> If you have nothing against this, I'll create a JIRA and commit the following 
> patch:
> 
> diff --git 
> a/core/src/main/java/org/apache/cxf/common/util/ProxyClassLoader.java 
> b/core/src/main/java/org/apache/cxf/common/util/ProxyClassLoader.java
> index f7de519..c4baa17 100644
> --- a/core/src/main/java/org/apache/cxf/common/util/ProxyClassLoader.java
> +++ b/core/src/main/java/org/apache/cxf/common/util/ProxyClassLoader.java
> @@ -32,10 +32,12 @@ public class ProxyClassLoader extends ClassLoader {
>     private final Set<ClassLoader> loaders = new HashSet<ClassLoader>();
>     private boolean checkSystem;
> 
> -    public ProxyClassLoader() {
> +    public ProxyClassLoader(ClassLoader parent) {
> +       super(parent);
>         classes = null;
>     }
> -    public ProxyClassLoader(Class<?>[] cls) {
> +    public ProxyClassLoader(ClassLoader parent, Class<?>[] cls) {
> +       super(parent);
>         classes = cls;
>     }
> 
> diff --git a/core/src/main/java/org/apache/cxf/common/util/ProxyHelper.java 
> b/core/src/main/java/org/apache/cxf/common/util/ProxyHelper.java
> index c252574..27f2c56 100644
> --- a/core/src/main/java/org/apache/cxf/common/util/ProxyHelper.java
> +++ b/core/src/main/java/org/apache/cxf/common/util/ProxyHelper.java
> @@ -58,7 +58,7 @@ public class ProxyHelper {
>         if (canSeeAllInterfaces(loader, interfaces)) {
>             return loader;
>         }
> -        ProxyClassLoader combined = new ProxyClassLoader(interfaces);
> +        ProxyClassLoader combined = new ProxyClassLoader(loader, interfaces);
>         for (Class<?> currentInterface : interfaces) {
>             combined.addLoader(currentInterface.getClassLoader());
>         }
> 
> Thanks
> Alessio
> 
> 
> 
> [1] 
> https://fisheye6.atlassian.com/changelog/cxf?cs=3898dbb3e29202c0d2942fb903fa29a7c16418a7
> 
> -- 
> Alessio Soldano
> Web Service Lead, JBoss
> 

-- 
Daniel Kulp
[email protected] - http://dankulp.com/blog
Talend Community Coder - http://coders.talend.com

Reply via email to