javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"", local:"myNewProperty"). Expected elements are <...list of existing properties...> at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:146) ...excitingly lengthy callstack... Caused by: javax.xml.bind.UnmarshalException - with linked exception: [javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"myNewProperty"). Expected elements are <...list of existing properties...>] at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:425) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362) at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:339) at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:755) at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:624) ...excitingly lengthy callstack...
This makes it a bit hard to update our server without updating the client in lockstep. We specifically wanted to be able to add attributes to entities without breaking our clients to avoid tying teams together too closely. Luckily it turns out that this problem can be ignored by providing a custom ValidationEventHandler as of CXF 2.2.4 using new properties added for CXF-2455. Unfortunately the event is not very distinct so we have to either follow worst-practices and examine the message to decide if this is the specific error we want to suppress or simply suppress all errors:
import javax.xml.bind.ValidationEvent; import javax.xml.bind.ValidationEventHandler; public class IgnoreUnexpectedElementsHandler implements ValidationEventHandler { @Override public boolean handleEvent(ValidationEvent event) { //true: keep going. In this case we only want to continue for the error we're trying to hide. return event.getMessage().startsWith("unexpected element ("); } }Note that for this example we're assuming our handler goes into the default package which isn't a particularly good idea in reality. Once we have created our validation event handler we need to tell our client to use it. In our case in the Spring configuration of the client:
<jaxws:client address="${a.property.for.my.services.url}" id="myServiceClient" serviceclass="com.something.myService"> <jaxws:properties> <entry key="jaxb-validation-event-handler" value-ref="ignoreUnexpectedElementsHandler"> </entry></jaxws:properties> </jaxws:client>Kind of lame to have to do really.
6 comments:
It can be done a little bit more easily by setting the "set-jaxb-validation-event-handler" flag to "false"
http://mail-archives.apache.org/mod_mbox/cxf-users/201001.mbox/%3C201001291547.56047.dkulp@apache.org%3E
Guys thx for solution!!
@icyitscold, your easy solution was sweet
@ROD, thanks for posting this question and the solution
خرید نهال بادام
"Thanks for this detailed explanation! Encountering an UnmarshalException due to server-side changes like adding an attribute can be tricky, especially when dealing with backward compatibility in web services. Your breakdown of the issue in the context of Scala and CXF is really helpful. It would be great to know if there are any other best practices to follow for maintaining compatibility between different versions of a service, especially in larger systems where schema changes might happen frequently.".
Digital Marketing Course In Ameerpet
Post a Comment