[jbossws-dev] Re: Improving JBossWS-CXF Client Side Integration

Richard Opalka ropalka at redhat.com
Thu Jun 4 01:31:09 EDT 2009


Hi Daniel,

   all the options mentioned below sound reasonable to me.

Richard

Daniel Kulp wrote:
> Richard,
>
> Modifying the generated code is not a doable solution.   That would tie them 
> to CXF which would then violate the JAX-WS spec and TCK and such.   Thus, 
> that's not an option.
>
> However, you could be on the right track.   In our ServiceImpl, all the 
> "getPort" calls forward into the protected "createPort" method (line 384 of 
> ServiceImpl).    We COULD put your call to the listener in there.
>
> The better option would be to push it even furthur into CXF and put it into 
> the JaxWsProxyFactoryBean/ClientProxyFactoryBean.create() call.     That way, 
> if they end up using the spring "jaxws:client" call or use the factories 
> directly themselves, the listeners would be invoked as well.
>
> Dan
>
>
>
> On Wed June 3 2009 2:11:22 am Richard Opalka wrote:
>   
>> Hi Daniel,
>>
>>    Yes, I know about solution 1) you suggested. However I don't like it.
>> It's hacky and could cause a lot of troubles to our customers.
>> Thus I'd like to go the way to modify CXF code base.
>>
>>    Before I'll write my suggestion let me clarify that we don't need to
>> wrap your ServiceDelegate. We just need to register properties
>> on the proxy and that can be achieved using listener approach.
>> So here are my thoughts how it could be achieved in another way (no
>> delegation):
>>
>> ---
>> ad1)
>> ---
>> // CXF provides listener interface
>> package org.apache.cxf.jaxws;
>>
>> public interface ServiceListener
>> {
>>    void onPortCreated(T proxy, Class<T> sei);
>> }
>> ---
>> ad2)
>> ---
>> // JBossWS provides listener implementation
>> package org.jboss.wsf.stack.cxf.client;
>>
>> public class ServiceListenerImpl implements ServiceListener
>> {
>>    public void onPortCreated(T proxy, Class<T> sei)
>>    {
>>       // ... our integration code
>>    }
>> }
>> ---
>> ad3)
>> ---
>> // JBossWS somehow registers the listener
>> ---
>> ad4)
>> ---
>> // finally replace the following code in
>> org.apache.cxf.jaxws.ServiceImpl.createPort(...)
>> protected <T> T createPort(QName portName, EndpointReferenceType epr,
>> Class<T> serviceEndpointInterface, WebServiceFeature... features)
>> {
>>    // ...
>>    return serviceEndpointInterface.cast(obj);
>> }
>> // with the following code:
>> protected <T> T createPort(QName portName, EndpointReferenceType epr,
>> Class<T> serviceEndpointInterface, WebServiceFeature... features)
>> {
>>    // ...
>>    T proxy = serviceEndpointInterface.cast(obj);
>>    for (ServiceListener listener : listeners)
>>    {
>>       listener.onPortCreated(proxy, serviceEndpointInterface);
>>    }
>>    return proxy;
>> }
>>
>> If you like this approach then let's disscuss how ad3) could be
>> achieved, i.e. how to register the listener on the service.
>>
>> Cheers,
>>
>> Richard
>>
>> Daniel Kulp wrote:
>>     
>>> Well, couple things spring to mind:
>>>
>>> Option 1: requires no changes to CXF, but requires some classloader magic
>>> on your side
>>> Write your own javax.xml.ws.spi.Provider that probably subclasses ours
>>> and overrides the method:
>>>     @Override
>>>     public ServiceDelegate createServiceDelegate(URL url, QName qname,
>>>                                              Class cls) {
>>>         Bus bus = BusFactory.getThreadDefaultBus();
>>>         return new ServiceImpl(bus, url, qname, cls);
>>>     }
>>>
>>> In your case, return a subclass of our ServiceImpl the does your
>>> additional stuff.   That way, any cast we may do to ServiceImpl would
>>> still work (not sure if we do it anywhere, but just in case).  That way,
>>> you won't really have an extra delegation layer.   Just overrides.    
>>> The TRICK is getting your provider to be used instead of ours.    Thus,
>>> you may need to make sure your
>>> META-INF/services/javax.xml.ws.spi.Provider  file is picked up before our
>>> (or use the system property to force yours).
>>>
>>>
>>> Option 2: make changes to CXF.   Couple of ideas here.  One could be in
>>> our createServiceDelegate method above, we do something like:
>>>
>>>
>>> Provider p = bus.getExtension(Provider.class);
>>> if (p != null) {
>>>     return p.createServiceDelegate(....);
>>> }
>>> return new ServiceImpl(....);
>>>
>>> or similar.   Thus, if a custom Provider is found on the Bus, we'll
>>> delegate to it.   Heck, we could also put a static "Provider delegate;"
>>> field on our ProviderImpl that you could set to your provider prior to
>>> any calls.
>>>
>>> Or, we could look for a property someplace for the name of the
>>> "ServiceImpl" class to instantiate.   If set, use reflection to create
>>> the ServiceImpl thing if set.
>>>
>>> Anyway, those are my immediate thoughts.
>>>
>>> Dan
>>>
>>> On Mon May 25 2009 9:21:35 am Richard Opalka wrote:
>>>       
>>>> Hi CXF Team,
>>>>
>>>>
>>>>    We've spent some time with CXF source code analysis but without
>>>> success. Related issue is: https://jira.jboss.org/jira/browse/JBWS-2521
>>>> We would like to remove one very ugly JBossWS CXF JAX-WS client proxy
>>>> integration hack related to service references (method
>>>> hackServiceDelegate()),
>>>> see:
>>>>
>>>> http://fpaste.org/paste/12892
>>>>
>>>>    We're registering our custom ServiceDelegate handler (via reflection)
>>>> in original proxy
>>>> and we delegate each call to CXF original service delegate there, with
>>>> one exception.
>>>> We're propagating service ref properties for every port creation before
>>>> returning
>>>> from our custom service delegate (method propagateProps(T proxy,
>>>> Class<T> serviceEndpointInterface)),
>>>> see:
>>>>
>>>> http://fpaste.org/paste/12893
>>>>
>>>>    Could you guys, with excellent CXF architecture knowledge, give us
>>>> some hints how
>>>> to improve our JBossWS CXF JAX-WS client integration and remove
>>>> aforementioned ugly hack?
>>>>
>>>> JBossWS Team
>>>>
>>>> PS: We're looking forward for your suggestions ;)
>>>>         
>
>   


-- 
Richard Opalka
JBoss Software Engineer

Mail: ropalka at redhat.com
Mobile: +420 731 186 942




More information about the jbossws-dev mailing list