cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jeff Genender <jgenen...@apache.org>
Subject Re: Improving JBossWS-CXF Client Side Integration
Date Wed, 03 Jun 2009 20:40:43 GMT
OSGI, Shmo-sgi! ;-)

Anyways, I am thinking more of a tiered approach to this.

I think the listener is fine, but its nice to be able to have the fall  
back property.  This gives you the best of both worlds.  This is kind  
of how we did in the JACC implementation in Geronimo IIRC. - then  
again... it's been a long while.

Thoughts?

Jeff


On Jun 3, 2009, at 1:44 PM, Daniel Kulp wrote:

> On Wed June 3 2009 3:18:36 pm Jeff Genender wrote:
>> I actually prefer the injection/override of an implementation via a
>> property...
>>
>> This is quite common (see the XML parser, JACC, etc) and sounds like
>> it could lend itself very well to what is trying to be done here.
>
> Just because its "quite common" doesn't mean it works well.  :-)   For
> example: the META-INF/services thing really does NOT work well in an  
> OSGi
> environment.   The ServiceMix folks have to have separate "api" jars  
> for
> everything that uses the META-INF/services stuff  that use a  
> different lookup
> mechanism.
>
> Plus, the whole META-INF/services thing really depends on classpath  
> ordering
> and such which users never seem to get right.   If CXF is first, it  
> would use
> CXF's and the JBoss customizations wouldn't trigger.   If JBoss's is  
> first,
> they would.
>
> That said, the listener thing Richard proposed has some additional  
> benefits as
> well when integrating into other containers such as ServiceMix or  
> Camel.
>
> Dan
>
>
>
>>
>> Jeff
>>
>> On Jun 3, 2009, at 1:13 PM, 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 ;)
>>>
>>> --
>>> Daniel Kulp
>>> dkulp@apache.org
>>> http://www.dankulp.com/blog
>
> -- 
> Daniel Kulp
> dkulp@apache.org
> http://www.dankulp.com/blog


Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message