PDA

View Full Version : JiBX unmarshalling - DOM error


rwilcom
Jun 23rd, 2006, 04:12 PM
I am using the JiBX marshaller/unmarshaller - when the XML message reaches the the endpoint class [a type of AbstractMarshallingPayloadEndpoint] I get an error that reads: "JibxMarshaller does not support unmarshalling of DOM Nodes..." - am I missing a property setting in the bean(s)??

I am using build .9 so I had to declare the JibxFactory bean (etc.) which is no longer required in 1.x, was this a bug that has been resolved in a more recent build?

thanks!
Ron

Arjen Poutsma
Jun 23rd, 2006, 06:03 PM
It is not a bug, it is a feature of Jibx mentioned in both the Javadoc and the reference manual (http://static.springframework.org/spring-ws/docs/1.0-m1/reference/html/oxm.html#oxm-jibx):


Note that the JibxMarshaller only operates on raw I/O streams, and not on DOM nodes, nor SAX handlers.


Since SAAJ is based on DOM, you cannot use it in combination with Jibx. Rather than convert the entire DOM tree to a byte buffer, and unmarshal from that, I decided to throw an exception and mention the behavior in the Javadocs, since the conversion process might be slow.

I could add an option to the JibxMarshaller to allow for this conversion, but I think the whole speed advantage of Jibx will go away.

It might be that this feature was fixes in the recently released Jibx 1.1, I have not checked that version out yet.

rwilcom
Jun 24th, 2006, 08:47 AM
OK- so how do I correct this? Is it a fix on the client side such that it does not send and XML SOAP block?? Or is it a fix on the server side not to convert the incoming XML to a SOAP message (so I should use a different dispatcher?)?

Can I get some more help/guidance on this one please? Any example code/cofiguration would be great.

Arjen Poutsma
Jun 24th, 2006, 12:00 PM
OK- so how do I correct this? Is it a fix on the client side such that it does not send and XML SOAP block?? Or is it a fix on the server side not to convert the incoming XML to a SOAP message (so I should use a different dispatcher?)?

Can I get some more help/guidance on this one please? Any example code/cofiguration would be great.

I'm sorry if I wasn't helpful before, let me improve on that.

The current implementation of the JibxMarshaller does not work with DOM, and therefore SAAJ. So you can either use a different Marshaller such as the Jaxb2Marshaller, or you can wait until I provide a fix for this.

My preferred way of fixing this is figuring out if Jibx 1.1 does support DOM, and use that. If that is not possible, I can convert incoming DOM documents to streams, and unmarshal from those. This conversion behavior will probably be optional, because it can decrease performance, and not all users will want that.

I've created a JIRA issue for this here (http://opensource.atlassian.com/projects/spring/browse/SWS-36), which you can track for progress.

Hope that makes things a little clearer,

rwilcom
Jun 25th, 2006, 08:31 AM
Ok, thanks - so lets say I wanted to use JiBX to take advantage of the performance? How do I do that without using DOM/SAAJ? I have control of both client and server so I am not against sending an XML I/O stream - but the question is how does it get dispatched to the proper marshaller/endpoint on the server side? The examples I have must parse to the SOAP body (payload element name) then on to the endpoint based on the value of the first element (tag) - is there some direct way to dispatch to an endpoint?

Correct me on this (?) - but the negative side to using JiBX is that it is not going to employ the standard web services protocol since the client can't send an XML SOAP (XML) message?

Arjen Poutsma
Jun 25th, 2006, 10:39 AM
Ok, thanks - so lets say I wanted to use JiBX to take advantage of the performance? How do I do that without using DOM/SAAJ?

I am currently working on a way to do this. The idea is to use Axiom instead of SAAJ for generating SOAP messages. Axiom is based on StAX, and JiBX supports StAX as well. However, the JibxMarshaller doesn't yet, but I'm working on it. So, when I'm done with this feature, you can use the AxiomSoapMessageContextFactory (instead of the SaajSoapMessageContextFactory), and all should be well.

I have control of both client and server so I am not against sending an XML I/O stream - but the question is how does it get dispatched to the proper marshaller/endpoint on the server side? The examples I have must parse to the SOAP body (payload element name) then on to the endpoint based on the value of the first element (tag) - is there some direct way to dispatch to an endpoint?

You can use an endpoint mapping which is not based on the content, such as the SoapActionEndpointMapping, which uses the SOAPAction HTTP header. It is used in the airline sample.

Cheers,

rwilcom
Jun 25th, 2006, 01:43 PM
So - let me make sure I am clear on this thread -

As of today's Spring WS release the JiBX implementation is not ready for use as a marshalling endpoint?

or

It "is ready" if you use the SOAP action header for dispatch and the cleint sends the body of the SOAP message as the bytes of the serialized object (or should the body contain the serialized JiBX output XML as a stream of bytes?)? Sorry if I sound a bit confused!

Bottom line - going back to one of the original posts - I should just use JAXB2 if I want to move foward with my development efforts and want to have standard SOAP XML as the client's message format?

thanks...

Ron

Arjen Poutsma
Jun 26th, 2006, 04:16 AM
As of today's Spring WS release the JiBX implementation is not ready for use as a marshalling endpoint?


Yes, that is the bottom line. It is a bit more subtle than this (see below), but in the end you cannot use Jibx as a Marshaller when using the AbstractMarshallerEndpoint today. That said, I hope to have this fixed by the end of the week.

Bottom line - going back to one of the original posts - I should just use JAXB2 if I want to move foward with my development efforts and want to have standard SOAP XML as the client's message format?


Yes you could, or you can wait a couple of days to have the JibxMarshaller fixed.

Here's the longer version of the above. Just some background knowledge, which changes nothing to the answers I gave. You may ignore it ;).

Having "standard SOAP XML" has nothing to do with the marshaller used. The central concept in SWS SOAP is the SoapMessage. There a two concrete implementations: SaajSoapMessage, which is based on a DOM tree, and AxiomSoapMessage, which is based on a StAX XMLStreamReader. The AbstractMarshallerEndpoint basically takes the body of the request message (using getPayloadSource()), and unmarshals that to a request Object. The response object is marshalled into the body of the response message (using getPayloadResult()). So the marshaller only reads from/writes to the body, and not the entire message.

Now, because SAAJ is based on DOM (i.e. getPayloadSource() returns a DOMSource), you currently cannot use it in combination with JiBX, because
the current JiBX version doesn't do DOM, only input streams. By the end of the week, you can use it, but it is not so fast because it converts SAAJ's DOM tree into a input stream first, and then unmarshals from that.

Luckily, JIBX 1.1 also supports StAX XMLStreamReaders. So by the end of the week, you will able to use the AxiomSoapMessage with the JibxMarshaller (both using XMLStreamReaders), and have optimal, streaming performance.

Cheers,

rwilcom
Jun 26th, 2006, 07:49 AM
Ok - I think I have this all straight now.

Thanks for all of your help!
Ron

decrypt
Jun 26th, 2006, 12:50 PM
Arjen,

Is this why I must return a DOMSource in my endpoint's implementation of getResponse() ? Because I get exceptions when I try to return anything but that...i.e. StreamSource/SAXSource.

Arjen Poutsma
Jun 27th, 2006, 06:53 AM
Arjen,

Is this why I must return a DOMSource in my endpoint's implementation of getResponse() ? Because I get exceptions when I try to return anything but that...i.e. StreamSource/SAXSource.

No, that's shouldn't be necessary. What Marshaller are you using?

decrypt
Jun 27th, 2006, 07:32 AM
Actually I'm using AbstractSaxPayloadEndpoint

If I attempt to return anything but a DOMSource in getResponse(), I get exceptions on the server-side.

Arjen Poutsma
Jun 27th, 2006, 09:04 AM
Hmm that sounds like a bug. Could you create an issue with the exact configuration and errors you get?

Thans,

decrypt
Jun 27th, 2006, 11:52 AM
I will try...but I don't ever get to see the actual exception...it start trying to create a soap fault response and then it errors on the fact that there is already a response object created...so there may be two bugs at play here...

decrypt
Jun 27th, 2006, 12:10 PM
I replaced WebLogic's XML related jars (Xerces, Xalan, xml-apis) and now i can return a SAXSource or a StreamSource just fine now.

rwilcom
Jun 27th, 2006, 01:30 PM
One more question about an ealier response to this thread:
"There a two concrete implementations: SaajSoapMessage, which is based on a DOM tree, and AxiomSoapMessage, which is based on a StAX XMLStreamReader. ..."

So - on the server-side, in order for Spring WS to use Axiom one would have to set the system property for the SOAP factory to the AxiomSoapFactory, correct? And, once this system property is set Spring WS will use the StAX based streamer only - and therefore, you must use the SOAPActionEndpointMapping dispatcher/mapper so it looks at the SOAPAction header. The PayloadRootQNameEndpointMapping dispatcher/mapper will no longer work on "that" deployment since it relies on the DOM tree (and the system won't be using SAAJ)?

Is this a correct statement?

Ron

Arjen Poutsma
Jun 28th, 2006, 02:52 AM
So - on the server-side, in order for Spring WS to use Axiom one would have to set the system property for the SOAP factory to the AxiomSoapFactory, correct?

No, you just have to change the SaajSoapMessageContextFactory in the application context to the AxiomSoapMessageContextFactory. That should be enough.

And, once this system property is set Spring WS will use the StAX based streamer only - and therefore, you must use the SOAPActionEndpointMapping dispatcher/mapper so it looks at the SOAPAction header. The PayloadRootQNameEndpointMapping dispatcher/mapper will no longer work on "that" deployment since it relies on the DOM tree (and the system won't be using SAAJ)?


No, the PayloadRootQNameEndpointMapping will work just fine, and so will the SoapActionEndpointMapping. It's just that the SoapActionEndpointMapping doesn't look in the contents of the message to dispatch it. That's why it's faster.
[/QUOTE]

Cheers,

Arjen Poutsma
Jun 28th, 2006, 02:54 AM
I replaced WebLogic's XML related jars (Xerces, Xalan, xml-apis) and now i can return a SAXSource or a StreamSource just fine now.

Good news. Perhaps I should place a big warning on how to upgrade the XML libraries in the reference documentation. Seems to affect a lot of people.

Thanks!

Arjen Poutsma
Jun 29th, 2006, 07:26 AM
The issue (http://opensource.atlassian.com/projects/spring/browse/SWS-36) that was the original topic of this thread should now be fixed in subversion. You can get the sources from

https://svn.sourceforge.net/svnroot/springframework/spring-projects/trunk/spring-ws/.

I will upload a snapshot that will contain this functionality tomorrow.

rwilcom
Jun 29th, 2006, 10:30 AM
Arjen,
Thanks for the fix! Was this an extensive update or a couple of blocks of code? Just curious, which classes and what areas were updated.

thanks again!
Ron

Arjen Poutsma
Jun 29th, 2006, 10:35 AM
Arjen,
Thanks for the fix! Was this an extensive update or a couple of blocks of code? Just curious, which classes and what areas were updated.

thanks again!
Ron

You're welcome! It was quite extensive, and it involved moving some ws-core code to a separate xml module, so that oxm could also use it. Then I wrote some more tests, and worked from there. I'm still not sure if I like the solution I have right now, but at least you have something to work with. The stuff I might change will be internal only, and shouldn't affect the public interface.

Cheers,

rwilcom
Jun 29th, 2006, 11:13 AM
How long until an M2 build is available (that will contain these updates)?

thanks.
Ron

Arjen Poutsma
Jun 30th, 2006, 02:52 AM
I will create a snapshot today, which will not be M2 but contains the stuff you need.

rwilcom
Jun 30th, 2006, 12:37 PM
Great! Where will I be able to download this - will it be under 'files' in sourceforge?

thanks,
Ron

rwilcom
Jul 7th, 2006, 10:03 AM
I am still wondering where I can get the snapshot of the Spring WS package that includes the JiBX (axiom soap factory) corrections? Any help or direction would be appreciated.

thanks!
Ron

Arjen Poutsma
Jul 7th, 2006, 10:48 AM
Look here.

rwilcom
Jul 20th, 2006, 09:41 AM
I have an M2 snapshot (the one with the JiBX fixes) - I am trying to move forward with using the JiBX marshalling implementation so I set it up to use the AxiomSoapMessageContextFactory. Now I am getting dependencies errors - my first was for JiBX itself (so I loaded the latest JiBX jars and got passed those)... now I am getting Axiom dependency failures. Says that the AxioumSoapMessageContextFactory cannot be initialized because it depends on class 'org.apache.axiom.om.OMException' - so, now I am downloading Axiom 1.0 ... but my question is when does this dependency landslide end?

What other dependencies am I going to run into here - trial and error is no fun.

thanks.
Ron

Arjen Poutsma
Jul 20th, 2006, 05:01 PM
SWS is a pretty flexible framework, which is hard to describe in maven2 dependencies. For instance, it does not require JiBX nor Axiom to work, that's why I set these dependencies as optional in the POM. The alternative would be to set them as required, but then everybody will download axiom, Jibx, castor, xlmbeans, etc. etc. Not a solution, IMO.

I think that they are going to implement something similar to Ivy configurations in maven 2.1, which should be useful. Then, I could just define an axiom or jibx configuration, and all deps would resolve automatically.

But to answer your question: the basic deps you need are (off the top of my head):


stax-api
a stax implementation (Woodstox is fast: wstx-asl)
axiom-api
axiom-impl
jibx-run
jibx-bind & bcel (only at compile time)


Cheers,