cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alessio Soldano <asold...@redhat.com>
Subject Re: JAXWS client proxy classloading with CXF 3.0
Date Wed, 02 Apr 2014 16:48:14 GMT
For the records: https://issues.apache.org/jira/browse/CXF-5668

On 02/04/14 16:23, Alessio Soldano wrote:
> Thanks,
> will do soon.
>
> On 02/04/14 16:17, Daniel Kulp wrote:
>>
>> That seems reasonable to me.   Feel free to apply it.
>>
>>
>> Dan
>>
>>
>> On Apr 2, 2014, at 8:00 AM, Alessio Soldano <asoldano@redhat.com> 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
>>>
>
>


-- 
Alessio Soldano
Web Service Lead, JBoss


Mime
View raw message