You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Benson Margulies <bi...@gmail.com> on 2010/10/11 14:20:00 UTC

Dug myself into a pit switching from Simple to JAX-WS

This would normally belong on user but it's a sort of followup to the
Simple conversation...

I switched my MTOM-ish service to JAX-WS, and now my MTOM items
disappear. My unit tests all fail with null pointers since the data
handlers have nothing in them. It all worked fine with Simple (and
using properties to enable MTOM)....

So, I made the service side look like:

SEI:

@WebService
public interface DocumentDatabase { ... }

Implementation class:

@WebService(endpointInterface = "com.basistech.jdd.DocumentDatabase")
@MTOM
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class ...

Service factory:

 JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
        svrFactory.setDataBinding(new AegisDatabinding());
        svrFactory.setServiceClass(DocumentDatabase.class);
        svrFactory.setAddress("http://localhost:" +
documentServicePort + "/documentDatabase");
        svrFactory.setServiceBean(impl);
        server = svrFactory.create();


Client factory:

JaxWsClientFactoryBean clientFactory = new JaxWsClientFactoryBean();
        clientFactory.setBindingId(SOAPBinding.SOAP11HTTP_MTOM_BINDING);
        JaxWsProxyFactoryBean factory = new
JaxWsProxyFactoryBean(clientFactory);
        factory.setDataBinding(new AegisDatabinding());
        // perhaps not needed given the endpointInterface annotation
        factory.setServiceClass(DocumentDatabase.class);
        factory.setAddress(serviceUrl);
        return (DocumentDatabase) factory.create();

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Daniel Kulp <dk...@apache.org>.
On Monday 11 October 2010 8:50:16 am Benson Margulies wrote:
> I know a little more about this now ....
> 
> When I used Simple, the effective MTOM threshold was zero. So the data
> was always in the InputStream of the data handler.
> 
> Well, hmm, with the code below, the data is ending up inline
> (presumably because it isn't big enough, or because I somehow failed
> below to turn on MTOM for the client side), and then the DataHandler
> has no input stream, just an object. This strikes me, as the
> implementor of the Aegis databinding, as perhaps a bug in the data
> binding, since it's a pain to have to check both places in the data
> handler, and so even if the data arrives out-of-line it would, I
> think, be better to also set up an input stream.

Yea.  I agree.   Making them consistent would be a good thing

For now, you can probably change the MTOM annotation to:

@MTOM(threshold = 1) or something real small.  (not sure if 0 works)

Dan



> 
> On Mon, Oct 11, 2010 at 8:20 AM, Benson Margulies <bi...@gmail.com> 
wrote:
> > This would normally belong on user but it's a sort of followup to the
> > Simple conversation...
> > 
> > I switched my MTOM-ish service to JAX-WS, and now my MTOM items
> > disappear. My unit tests all fail with null pointers since the data
> > handlers have nothing in them. It all worked fine with Simple (and
> > using properties to enable MTOM)....
> > 
> > So, I made the service side look like:
> > 
> > SEI:
> > 
> > @WebService
> > public interface DocumentDatabase { ... }
> > 
> > Implementation class:
> > 
> > @WebService(endpointInterface = "com.basistech.jdd.DocumentDatabase")
> > @MTOM
> > @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
> > public class ...
> > 
> > Service factory:
> > 
> >  JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
> >        svrFactory.setDataBinding(new AegisDatabinding());
> >        svrFactory.setServiceClass(DocumentDatabase.class);
> >        svrFactory.setAddress("http://localhost:" +
> > documentServicePort + "/documentDatabase");
> >        svrFactory.setServiceBean(impl);
> >        server = svrFactory.create();
> > 
> > 
> > Client factory:
> > 
> > JaxWsClientFactoryBean clientFactory = new JaxWsClientFactoryBean();
> >        clientFactory.setBindingId(SOAPBinding.SOAP11HTTP_MTOM_BINDING);
> >        JaxWsProxyFactoryBean factory = new
> > JaxWsProxyFactoryBean(clientFactory);
> >        factory.setDataBinding(new AegisDatabinding());
> >        // perhaps not needed given the endpointInterface annotation
> >        factory.setServiceClass(DocumentDatabase.class);
> >        factory.setAddress(serviceUrl);
> >        return (DocumentDatabase) factory.create();

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Benson Margulies <bi...@gmail.com>.
I know a little more about this now ....

When I used Simple, the effective MTOM threshold was zero. So the data
was always in the InputStream of the data handler.

Well, hmm, with the code below, the data is ending up inline
(presumably because it isn't big enough, or because I somehow failed
below to turn on MTOM for the client side), and then the DataHandler
has no input stream, just an object. This strikes me, as the
implementor of the Aegis databinding, as perhaps a bug in the data
binding, since it's a pain to have to check both places in the data
handler, and so even if the data arrives out-of-line it would, I
think, be better to also set up an input stream.

On Mon, Oct 11, 2010 at 8:20 AM, Benson Margulies <bi...@gmail.com> wrote:
> This would normally belong on user but it's a sort of followup to the
> Simple conversation...
>
> I switched my MTOM-ish service to JAX-WS, and now my MTOM items
> disappear. My unit tests all fail with null pointers since the data
> handlers have nothing in them. It all worked fine with Simple (and
> using properties to enable MTOM)....
>
> So, I made the service side look like:
>
> SEI:
>
> @WebService
> public interface DocumentDatabase { ... }
>
> Implementation class:
>
> @WebService(endpointInterface = "com.basistech.jdd.DocumentDatabase")
> @MTOM
> @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
> public class ...
>
> Service factory:
>
>  JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
>        svrFactory.setDataBinding(new AegisDatabinding());
>        svrFactory.setServiceClass(DocumentDatabase.class);
>        svrFactory.setAddress("http://localhost:" +
> documentServicePort + "/documentDatabase");
>        svrFactory.setServiceBean(impl);
>        server = svrFactory.create();
>
>
> Client factory:
>
> JaxWsClientFactoryBean clientFactory = new JaxWsClientFactoryBean();
>        clientFactory.setBindingId(SOAPBinding.SOAP11HTTP_MTOM_BINDING);
>        JaxWsProxyFactoryBean factory = new
> JaxWsProxyFactoryBean(clientFactory);
>        factory.setDataBinding(new AegisDatabinding());
>        // perhaps not needed given the endpointInterface annotation
>        factory.setServiceClass(DocumentDatabase.class);
>        factory.setAddress(serviceUrl);
>        return (DocumentDatabase) factory.create();
>

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Benson Margulies <bi...@gmail.com>.
This is all writing. The original Aegis implementation had a boolean,
initialized at setup of the binding, to control whether it wrote MTOM.
I didn't disturb that. I don't have any problem in principle with
making it look at a contextual property, give or take the fact that
the code in question isn't anywhere near an object that has them. So
I'll do one of these things when I address this.

Keep in mind that the following does work...


Map<String, Object> props = new HashMap<String, Object>();
        props.put("mtom-enabled", Boolean.TRUE);
        JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
        svrFactory.setDataBinding(new AegisDatabinding());
        svrFactory.setProperties(props);
        svrFactory.setServiceClass(Analysis.class);
        svrFactory.setAddress(analysisServiceHttpURL);
        svrFactory.setServiceBean(analyzer);
        soapServer = svrFactory.create();


How hard could it be to make this 'magic' inside the JaxWsServerFactoryBean?

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Daniel Kulp <dk...@apache.org>.
On Monday 11 October 2010 4:57:37 pm Benson Margulies wrote:
> On Mon, Oct 11, 2010 at 1:35 PM, Daniel Kulp <dk...@apache.org> wrote:
> > 
> > At some point in there (would need to debug through), I believe the
> > JAX-WS SoapBinding thing
> > (org/apache/cxf/jaxws/binding/soap/SOAPBindingImpl) sets the property
> > onto the BindingInfo.    From there, the AttachmentOutInterceptor
> > queries that via a message.getContextualProperty(....).   That is enough
> > for it to setup the MIME stuff and create the AttachmentSerializer
> > object.   That SHOULD be all that is needed.    The places that call the
> > databindings/datawriter write method will first call
> > writer.setAttachments(...) if the MIME stuff is setup.    That's all the
> > databinding should need to ENABLE MTOM.   The threshold thing is
> > completely different.  I'm not even sure if that is working properly
> > with JAXB.   Need to dig more.
> 
> It is absolutely not enough for Aegis. In Aegis, the interceptor won't
> find anything to do unless the DataHandlerType has set up the
> attachment. The DataHandlerType won't setup any attachments unless the
> mtom flag is set in the Aegis context, and that flag won't be set
> unless the ServiceImpl had the MTOM_ENABLED property ... which it
> lacks with JAX-WS but has with Simple. 

Or Aegis could call message.getContextualProperty(..) to match what the 
AttachmentOutInterceptor does.   Or Aegis could call 
service.getEndpointInfo().getBinding().get(MTOM_ENABLED) so it's in one place.  
or. ....    Bunches of options.   Pick one.  :-)

> It should be easy enough to
> make JAX-WS add that property to the ServiceImpl; is there any reason
> not to? 

Well,it's not as easy as you think.   Something like:

<jaxws:endpoint  ......>
   <jaxws:properties>
        <entry key="mtom-enabled" value="true"/>
...

should also work, but that just sets the properties on the EndpointInfo, which 
isn't the ServiceImpl OR the Binding.   That's why the getContextualProperty  
call is valuable.  

> And also stick the threshold out there so Aegis could learn to
> use it?

Hold on....  are we talking READING or WRITING?

Those are two very different situations.  For READING, we shouldn't require a 
setting anywhere.   If the message comes in in MIME format, it should just 
turn itself on automatically.  The incoming side may not have any control over 
what the other end of the wire sends.   If they send in MTOM, we should just 
accept it.

For WRITING, the databinding really needs to use the same method that the 
AttachmentOutInterceptor uses.   If AttachmentOut doesn't detect that it 
should be MTOM, then the databinding really shouldn't try as the wire won't be 
setup for it.   (no mime wrappers)




-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Benson Margulies <bi...@gmail.com>.
On Mon, Oct 11, 2010 at 1:35 PM, Daniel Kulp <dk...@apache.org> wrote:
>
> Re-adding dev@.....
>
> On Monday 11 October 2010 9:50:01 am Benson Margulies wrote:
>> > Interesting.  Not sure how the databinding would have any affect on
>> > wether MTOM is enabled or not.  The JAX-WS frontend should just be
>> > setting the Message.MTOM_ENABLED property on the endpoint and the
>> > AttachmentOutInterceptor picks that up and sets up the attachments.
>>
>> It looks, superficially, as if JAX-WS is not setting that property
>> where Aegis looks for it.
>>
>> I crossreferenced org.apache.cxf.message.Message.MTOM_ENABLED. I can
>> see no connection to @MTOM. MTOM_ENABLED is turned on based on the
>> 'deprecated?' binding ID in
>> org.apache.cxf.jaxws.JaxWsClientFactoryBean.setBindingId(String).
>>
>> That function sets the boolean in the config, and
>> org.apache.cxf.binding.soap.SoapBindingFactory.createBindingInfo(ServiceInf
>> o, String, Object) then sets MTOM_ENABLED.
>>
>> Also JaxWsServiceFactoryBean maps @MTOM to the @MTOMFeature, but I
>> can't find a trail connecting that to MTOM_ENABLED.
>
> At some point in there (would need to debug through), I believe the JAX-WS
> SoapBinding thing (org/apache/cxf/jaxws/binding/soap/SOAPBindingImpl) sets the
> property onto the BindingInfo.    From there, the AttachmentOutInterceptor
> queries that via a message.getContextualProperty(....).   That is enough for
> it to setup the MIME stuff and create the AttachmentSerializer object.   That
> SHOULD be all that is needed.    The places that call the
> databindings/datawriter write method will first call
> writer.setAttachments(...) if the MIME stuff is setup.    That's all the
> databinding should need to ENABLE MTOM.   The threshold thing is completely
> different.  I'm not even sure if that is working properly with JAXB.   Need to
> dig more.

It is absolutely not enough for Aegis. In Aegis, the interceptor won't
find anything to do unless the DataHandlerType has set up the
attachment. The DataHandlerType won't setup any attachments unless the
mtom flag is set in the Aegis context, and that flag won't be set
unless the ServiceImpl had the MTOM_ENABLED property ... which it
lacks with JAX-WS but has with Simple. It should be easy enough to
make JAX-WS add that property to the ServiceImpl; is there any reason
not to? And also stick the threshold out there so Aegis could learn to
use it?

>
> Dan
>
>
>
>
>>
>>
>> Threshold would require
>>
>> > databinding support.
>>
>> Well, right. Aegis looks for MTOM_ENABLED and respects it (creating
>> attachments for certain data types) but does not look at
>> MTOM_THRESHOLD at all.
>>
>> > Strange.
>> > Dan
>> >
>> >> So, in trying to switch from Simple to JAX-WS, I removed the
>> >> setting of the 'mtom-enabled' property, and turned it off altogether.
>> >> That triggered the assymetry.
>> >
>> > --
>> > Daniel Kulp
>> > dkulp@apache.org
>> > http://dankulp.com/blog
>
> --
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
>

Re: Dug myself into a pit switching from Simple to JAX-WS

Posted by Daniel Kulp <dk...@apache.org>.
Re-adding dev@.....

On Monday 11 October 2010 9:50:01 am Benson Margulies wrote:
> > Interesting.  Not sure how the databinding would have any affect on
> > wether MTOM is enabled or not.  The JAX-WS frontend should just be
> > setting the Message.MTOM_ENABLED property on the endpoint and the
> > AttachmentOutInterceptor picks that up and sets up the attachments.
> 
> It looks, superficially, as if JAX-WS is not setting that property
> where Aegis looks for it.
>
> I crossreferenced org.apache.cxf.message.Message.MTOM_ENABLED. I can
> see no connection to @MTOM. MTOM_ENABLED is turned on based on the
> 'deprecated?' binding ID in
> org.apache.cxf.jaxws.JaxWsClientFactoryBean.setBindingId(String).
> 
> That function sets the boolean in the config, and
> org.apache.cxf.binding.soap.SoapBindingFactory.createBindingInfo(ServiceInf
> o, String, Object) then sets MTOM_ENABLED.
> 
> Also JaxWsServiceFactoryBean maps @MTOM to the @MTOMFeature, but I
> can't find a trail connecting that to MTOM_ENABLED.

At some point in there (would need to debug through), I believe the JAX-WS 
SoapBinding thing (org/apache/cxf/jaxws/binding/soap/SOAPBindingImpl) sets the 
property onto the BindingInfo.    From there, the AttachmentOutInterceptor 
queries that via a message.getContextualProperty(....).   That is enough for 
it to setup the MIME stuff and create the AttachmentSerializer object.   That 
SHOULD be all that is needed.    The places that call the 
databindings/datawriter write method will first call 
writer.setAttachments(...) if the MIME stuff is setup.    That's all the  
databinding should need to ENABLE MTOM.   The threshold thing is completely 
different.  I'm not even sure if that is working properly with JAXB.   Need to 
dig more.

Dan




> 
> 
> Threshold would require
> 
> > databinding support.
> 
> Well, right. Aegis looks for MTOM_ENABLED and respects it (creating
> attachments for certain data types) but does not look at
> MTOM_THRESHOLD at all.
> 
> > Strange.
> > Dan
> > 
> >> So, in trying to switch from Simple to JAX-WS, I removed the
> >> setting of the 'mtom-enabled' property, and turned it off altogether.
> >> That triggered the assymetry.
> > 
> > --
> > Daniel Kulp
> > dkulp@apache.org
> > http://dankulp.com/blog

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog