You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Richard Opalka <ro...@redhat.com> on 2009/05/25 15:21:35 UTC
Improving JBossWS-CXF Client Side Integration
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 ;)
--
B.Sc. Richard Opalka
Senior Software Engineer
JBoss, a division of Red Hat
Mobile: +420 731 186 942
Mail: ropalka@redhat.com
Re: Improving JBossWS-CXF Client Side Integration
Posted by Alessio Soldano <as...@redhat.com>.
Hi Dan and Richard,
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.
I would not say it's hacky, as providing a custom
javax.xml.ws.spi.Provider impl is something quite common.
However, just to clarify, should another solution be found and put in
place without much trouble, I'd prefer that. The reason being we've
doing something similar (leveraging the META-INF/service load system) in
other area in the past and that taught us this can lead to a lot of
misunderstandings with users building up the classpath the wrong way and
thus not getting things working.
Thanks for the collaboration Dan.
Cheers
Alessio
--
Alessio Soldano
Web Service Lead
JBoss, a division of Red Hat
Re: Improving JBossWS-CXF Client Side Integration
Posted by Alessio Soldano <as...@redhat.com>.
Hi Dan,
Daniel Kulp wrote:
> On Tue July 21 2009 11:25:56 am Alessio Soldano wrote:
>
>> The ServiceImpl gets the configurer from the bus after having created
>> the jaxws proxy factory bean.
>> Then my custom configurer sets the props in the JaxWSProxyFactoryBean
>> which in turns copies them to the request context in method
>> clientClientProxy(Client c), that is called when getting the port.
>>
>> Now, here are my few questions:
>> - could this be considered a proper use of the Configurer?
>>
>
> Actually, this is EXACTLY the right use of the Configurer. Good catch.
> It's specifically there so the container can provide configuration to the
> various beans used throughout CXF.
>
OK, thanks for confirmation.
>> I've found
>> just one implementation of this interface, for something related to
>> spring configuration
>>
>
> Our normal config mechanism is spring based. Thus, that's the implementation
> that is used most often. I don't know if your JBoss integration stuff
> exposes any of the spring config to the JBoss/CXF users. If so, you may need
> to keep the Spring configurer and "wrapper" it with yours. :
> Configurer orig = bus.getExtension(Configurer.class)
> bus.setExtension(new ServiceRefStubPropertyConfigurer(serviceRef, orig),
> Configurer.class);
>
> and have it call the wrapped configurer as well.
>
I've switched to the wrapper approach, just to be sure I'm not reducing
user's ability to set a configurer on its own (even if it's actually not
possible in the usecase that led us to this issue).
>> - I see Configurer has two methods:
>> void configureBean(Object beanInstance);
>> void configureBean(String name, Object beanInstance);
>>
>> I'd actually add another call for the configuration in ServiceImpl using
>> the former (configureBean(Object beanInstance)) as technically speaking
>> the latter seems to me to be used for configuring beans of a specific
>> name and currently the ServiceImpl uses that for
>> portName+".jaxws-client.proxyFactory" beans.
>>
> I'd double check that. Instead of "adding", you MAY be able to just replace
> as I think the default of configureBean(Object beanInstance) is to call a
> getName on the instance and then call the other method.
>
I'd leave everything as is currently then. Btw having implemented my
configurer as a wrapper, I call a private method in my configurer from
each of the two methods and then delegate to the corresponding method in
the wrapped configurer. So everything should go on working as originally
meant ;-)
>> Let me know what do you think, considering you said this could be of use
>> also for integrations issues besides JBossWS.
>>
>
> Sounds perfect!
>
OK, thanks for the insight on this.
Cheers
Alessio
--
Alessio Soldano
Web Service Lead, JBoss
Re: CXF WorkQueueManager : How to see the mbean on Jboss
Posted by Eoghan Glynn <eo...@gmail.com>.
Note that in order for any CXF MBean to actually be exposed, you'll
have to enable the IntrumentationManager (which is disabled by
default).
See [1] for details.
Cheers,
Eoghan
[1] http://cwiki.apache.org/CXF20DOC/jmx-management.html
2009/7/21 Rao, Sameer V <SR...@amfam.com>:
> CXF Asynch processing creates a ThreadPool and registers itself as
> MBean. How/Under which object name does that appear in JBossAS4.3
> container?
>
CXF WorkQueueManager : How to see the mbean on Jboss
Posted by "Rao, Sameer V" <SR...@amfam.com>.
CXF Asynch processing creates a ThreadPool and registers itself as
MBean. How/Under which object name does that appear in JBossAS4.3
container?
Re: Improving JBossWS-CXF Client Side Integration
Posted by Daniel Kulp <dk...@apache.org>.
On Tue July 21 2009 11:25:56 am Alessio Soldano wrote:
> I'm taking this from Richard as he's busy with other things. I've just
> taken a look deep in details and I think CXF already provides us a mean
> of setting properties in the port (actually in the request context upon
> port creation).
> I've just tried leveraging the bus extensions in ServiceImpl and it
> seems to work:
>
> bus.setExtension(new ServiceRefStubPropertyConfigurer(serviceRef),
> Configurer.class);
>
> ...
>
> public class ServiceRefStubPropertyConfigurer implements Configurer
> {
> ...
> public void configureBean(String name, Object beanInstance)
> {
> if (beanInstance instanceof JaxWsProxyFactoryBean)
> {
> ... //here we set the props in the jaxws proxy factory bean
> }
> }
> }
>
> The ServiceImpl gets the configurer from the bus after having created
> the jaxws proxy factory bean.
> Then my custom configurer sets the props in the JaxWSProxyFactoryBean
> which in turns copies them to the request context in method
> clientClientProxy(Client c), that is called when getting the port.
>
> Now, here are my few questions:
> - could this be considered a proper use of the Configurer?
Actually, this is EXACTLY the right use of the Configurer. Good catch.
It's specifically there so the container can provide configuration to the
various beans used throughout CXF.
> I've found
> just one implementation of this interface, for something related to
> spring configuration
Our normal config mechanism is spring based. Thus, that's the implementation
that is used most often. I don't know if your JBoss integration stuff
exposes any of the spring config to the JBoss/CXF users. If so, you may need
to keep the Spring configurer and "wrapper" it with yours. :
Configurer orig = bus.getExtension(Configurer.class)
bus.setExtension(new ServiceRefStubPropertyConfigurer(serviceRef, orig),
Configurer.class);
and have it call the wrapped configurer as well.
> - I see Configurer has two methods:
> void configureBean(Object beanInstance);
> void configureBean(String name, Object beanInstance);
>
> I'd actually add another call for the configuration in ServiceImpl using
> the former (configureBean(Object beanInstance)) as technically speaking
> the latter seems to me to be used for configuring beans of a specific
> name and currently the ServiceImpl uses that for
> portName+".jaxws-client.proxyFactory" beans.
I'd double check that. Instead of "adding", you MAY be able to just replace
as I think the default of configureBean(Object beanInstance) is to call a
getName on the instance and then call the other method.
> Let me know what do you think, considering you said this could be of use
> also for integrations issues besides JBossWS.
Sounds perfect!
--
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog
Re: Improving JBossWS-CXF Client Side Integration
Posted by Richard Opalka <ro...@redhat.com>.
OK, will do ;)
Richard
Daniel Kulp wrote:
> 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
>>>>>>
>
>
--
Richard Opalka
JBoss Software Engineer
Mail: ropalka@redhat.com
Mobile: +420 731 186 942
Re: Improving JBossWS-CXF Client Side Integration
Posted by Daniel Kulp <dk...@apache.org>.
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
Re: Improving JBossWS-CXF Client Side Integration
Posted by Richard Opalka <ro...@redhat.com>.
What's the current status of this issue Daniel?
Should I create JIRA issue or is there already one?
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
>>>>
>>
>>
>
>
--
Richard Opalka
JBoss Software Engineer
Mail: ropalka@redhat.com
Mobile: +420 731 186 942
Re: Improving JBossWS-CXF Client Side Integration
Posted by Richard Opalka <ro...@redhat.com>.
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
>>>
>
>
--
Richard Opalka
JBoss Software Engineer
Mail: ropalka@redhat.com
Mobile: +420 731 186 942
Re: Improving JBossWS-CXF Client Side Integration
Posted by Jeff Genender <jg...@apache.org>.
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
Re: Improving JBossWS-CXF Client Side Integration
Posted by Daniel Kulp <dk...@apache.org>.
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
Re: Improving JBossWS-CXF Client Side Integration
Posted by Jeff Genender <jg...@apache.org>.
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.
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
Re: Improving JBossWS-CXF Client Side Integration
Posted by Richard Opalka <ro...@redhat.com>.
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@redhat.com
Mobile: +420 731 186 942
Re: Improving JBossWS-CXF Client Side Integration
Posted by Alessio Soldano <as...@redhat.com>.
Hi Dan,
I'm taking this from Richard as he's busy with other things. I've just
taken a look deep in details and I think CXF already provides us a mean
of setting properties in the port (actually in the request context upon
port creation).
I've just tried leveraging the bus extensions in ServiceImpl and it
seems to work:
bus.setExtension(new ServiceRefStubPropertyConfigurer(serviceRef),
Configurer.class);
...
public class ServiceRefStubPropertyConfigurer implements Configurer
{
...
public void configureBean(String name, Object beanInstance)
{
if (beanInstance instanceof JaxWsProxyFactoryBean)
{
... //here we set the props in the jaxws proxy factory bean
}
}
}
The ServiceImpl gets the configurer from the bus after having created
the jaxws proxy factory bean.
Then my custom configurer sets the props in the JaxWSProxyFactoryBean
which in turns copies them to the request context in method
clientClientProxy(Client c), that is called when getting the port.
Now, here are my few questions:
- could this be considered a proper use of the Configurer? I've found
just one implementation of this interface, for something related to
spring configuration
- I see Configurer has two methods:
void configureBean(Object beanInstance);
void configureBean(String name, Object beanInstance);
I'd actually add another call for the configuration in ServiceImpl using
the former (configureBean(Object beanInstance)) as technically speaking
the latter seems to me to be used for configuring beans of a specific
name and currently the ServiceImpl uses that for
portName+".jaxws-client.proxyFactory" beans.
Let me know what do you think, considering you said this could be of use
also for integrations issues besides JBossWS.
Thanks
Alessio
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 ;)
>>>>
>
>
--
Alessio Soldano
Web Service Lead, JBoss
Re: Improving JBossWS-CXF Client Side Integration
Posted by Daniel Kulp <dk...@apache.org>.
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
Re: Improving JBossWS-CXF Client Side Integration
Posted by Richard Opalka <ro...@redhat.com>.
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@redhat.com
Mobile: +420 731 186 942
Re: Improving JBossWS-CXF Client Side Integration
Posted by Daniel Kulp <dk...@apache.org>.
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