cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Kulp <dk...@apache.org>
Subject Re: Improving JBossWS-CXF Client Side Integration
Date Mon, 15 Jun 2009 13:57:18 GMT
On Mon June 15 2009 9:39:51 am Richard Opalka wrote:
> What's the current status of this issue Daniel?
> Should I create JIRA issue or is there already one?

Create a JIRA (and attach a patch ;-)  )!

Dan


>
> Richard
>
> Richard Opalka wrote:
> > Hi CXF Folks,
> >
> >   see in lined comments below:
> >
> > 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.
> >
> > This is exactly the reason why I don't like META-INF/services
> > suggested fix. We have many
> > complaining users on our forums about Stack XYZ doesn't work. Many
> > times its because
> > their IDE isn't configured properly. Users would need to take care
> > also about classpath ordering
> > if we would go this way.
> >
> >> 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
View raw message