10 Replies Latest reply: Dec 6, 2012 6:36 AM by 726437 RSS

    JAX-WS fails to unmarshal payload due to strict namespaces

    726437
      I have a web service that receives the following payload
      <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
           <soap-env:Header/>
           <soap-env:Body>
                <mm7:DeliverReq xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0">
                     <MM7Version>5.3.0</MM7Version>
                </mm7:DeliverReq>
           </soap-env:Body>
      </soap-env:Envelope>
      I have generated classes for the schema using xjc, and created a webservice with an endpoint interface to receive it
      @WebService(name = "deliver")
      @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
      @XmlSeeAlso({
           org._3gpp.ftp.specs.archive._23_series._23_140.schema.rel_5_mm7_1_0.ObjectFactory.class
      })
      public interface Rel5Mm710ReceiverApi {
           @WebMethod(action = "deliverRequest")
           @WebResult(name = "DeliverRsp", targetNamespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0")
           public DeliverRspType deliverRequest(
                     @WebParam(name = "DeliverReq", targetNamespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0")
                    DeliverReqType request);
      }
      @WebService(serviceName = "soap")
      @HandlerChain(file = "handler.xml")
      public class InboundApi implements Rel5Mm710ReceiverApi {
           @Override
           @WebMethod
           public DeliverRspType deliverRequest(DeliverReqType request) {
                ...
           }
      }
      When I deploy this service on jboss as 7.1 and test it with soap ui by sending in the payload shown above, I get the following error:
      10:52:56,107 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http--127.0.0.1-8080-1) Interceptor for {http://mms.tele2.returia.nrk.no/}soap#{http://api.mm7.returia.nrk.no/}deliverRequest has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"", local:"MM7Version"). Expected elements are <{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}MMSRelayServerID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Content>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}ReplyChargingID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Priority>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Recipients>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}TimeStamp>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Sender>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}MM7Version>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}LinkedID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Subject> 
           at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:801)
           at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:642)
           at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:156)
           at org.apache.cxf.interceptor.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:201)
           at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
           at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
           at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:207)
           ...
      Caused by: javax.xml.bind.UnmarshalException
       - with linked exception:
      [javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"MM7Version"). Expected elements are <{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}MMSRelayServerID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Content>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}ReplyChargingID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Priority>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Recipients>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}TimeStamp>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Sender>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}MM7Version>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}LinkedID>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Subject>]
           at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:434)
           at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:371)
           at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:348)
           at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:778)
           ... 31 more
      The funny thing is, if I try to unmarshal this using JAXB, I get no errors at all. If I try to modify the payload so that it is like this:
      <mm7:DeliverReq xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0">
           <mm7:MM7Version>5.3.0</mm7:MM7Version>
      </mm7:DeliverReq>
      I also get no errors. Obviously changing the payload is not an option since I cant control what 3rd parties are sending me.

      How can I get rid of this error? How can I tell JAX-WS to not be so strict regarding namespaces?

      I have tried using a SOAPHandler to set some properties or other, but no amount of googeling has led me to the correct solution. Since JAXB is able to unmarshal this, then surly it must be possible to make JAX-WS do this as well?
        • 1. Re: JAX-WS fails to unmarshal payload due to strict namespaces
          jtahlborn
          The xml you are receiving is using elementFormDefault "unqualified". i believe you can use the @XmlSchema annotation to control this in setting jaxb (and probably jaxws).
          • 2. Re: JAX-WS fails to unmarshal payload due to strict namespaces
            726437
            The generated code from the schema produces this in package-info.java
            @javax.xml.bind.annotation.XmlSchema(
                      namespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0", 
                      elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
            package org._3gpp.ftp.specs.archive._23_series._23_140.schema.rel_5_mm7_1_0;
            I tried to set it to UNQUALIFIED instead, but this only shifts the problem to sub elements further down.
            10:33:31,601 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http-127.0.0.1-127.0.0.1-8080-1) Interceptor for {http://mms.tele2.returia.nrk.no/}soap#{http://api.mm7.returia.nrk.no/}deliverRequest has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"", local:"To"). Expected elements are <{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Bcc>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}Cc>,<{http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0}To> 
                 at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:801)
                 at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:642)
                 at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:156)
                    ...
            The offending element is defined like this:
            @XmlAccessorType(XmlAccessType.FIELD)
            @XmlType(name = "recipientsType", propOrder = {
                "toOrCcOrBcc"
            })
            public class RecipientsType {
            
                @XmlElementRefs({
                    @XmlElementRef(name = "To", namespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0", type = JAXBElement.class),
                    @XmlElementRef(name = "Cc", namespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0", type = JAXBElement.class),
                    @XmlElementRef(name = "Bcc", namespace = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0", type = JAXBElement.class)
                })
                protected List<JAXBElement<MultiAddressType>> toOrCcOrBcc;
            
                public List<JAXBElement<MultiAddressType>> getToOrCcOrBcc() {
                    if (toOrCcOrBcc == null) {
                        toOrCcOrBcc = new ArrayList<JAXBElement<MultiAddressType>>();
                    }
                    return this.toOrCcOrBcc;
                }
            
            }
            I would rather not make too many changes to generated code to solve this, since it will be gone the next time someone generates it again.
            • 3. Re: JAX-WS fails to unmarshal payload due to strict namespaces
              jtahlborn
              can you show the xml which is failing to parse now? that looks different from your original posted xml.
              • 4. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                726437
                I shortened it down a bit. The complete xml is as follows:
                <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
                     <soap-env:Header>
                          <mm7:TransactionID xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0" soap-env:mustUnderstand="1">MMS_92_20121108160143710</mm7:TransactionID>
                     </soap-env:Header>
                     <soap-env:Body>
                          <mm7:DeliverReq xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0">
                               <MM7Version>5.3.0</MM7Version>
                               <MMSRelayServerID>1234567890</MMSRelayServerID>
                               <LinkedID>h9a08sjxgb8a92</LinkedID>
                               <Sender>
                                    <Number displayOnly="false">12345678</Number>
                               </Sender>
                               <Recipients>
                                    <To>
                                         <ShortCode displayOnly="false">12345</ShortCode>
                                    </To>
                               </Recipients>
                               <TimeStamp>2012-11-08T16:01:43+01:00</TimeStamp>
                               <ReplyChargingID>NoReplyChargingMessageID</ReplyChargingID>
                               <Priority>Normal</Priority>
                               <Subject>Subject</Subject>
                               <Content href="/mms/mm7/mm7client" allowAdaptations="false" />
                          </mm7:DeliverReq>
                     </soap-env:Body>
                </soap-env:Envelope>
                When set to UNQUALIFIED it fails on the subelements of <Recipients>...</Recipients>. The generated code of this element is shown in my previous post.
                • 5. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                  jtahlborn
                  is the "RecipientsType" in a different namespace from all the other elemens?
                  • 6. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                    726437
                    No its the same namespace.
                    • 7. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                      jtahlborn
                      MortenN wrote:
                      No its the same namespace.
                      shouldn't the XmlType have the namespace then? do the other classes in the namespace include the namespace in the XmlType annotation?
                      • 8. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                        726437
                        Its all generated code. If you use xjc on the schema at http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0 you can see all the code that is generated.
                        • 9. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                          jmsjr
                          MortenN wrote:
                          I shortened it down a bit. The complete xml is as follows:
                          <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
                               <soap-env:Header>
                                    <mm7:TransactionID xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0" soap-env:mustUnderstand="1">MMS_92_20121108160143710</mm7:TransactionID>
                               </soap-env:Header>
                               <soap-env:Body>
                                    <mm7:DeliverReq xmlns:mm7="http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-5-MM7-1-0">
                                         <MM7Version>5.3.0</MM7Version>
                                         <MMSRelayServerID>1234567890</MMSRelayServerID>
                                         <LinkedID>h9a08sjxgb8a92</LinkedID>
                                         <Sender>
                                              <Number displayOnly="false">12345678</Number>
                                         </Sender>
                                         <Recipients>
                                              <To>
                                                   <ShortCode displayOnly="false">12345</ShortCode>
                                              </To>
                                         </Recipients>
                                         <TimeStamp>2012-11-08T16:01:43+01:00</TimeStamp>
                                         <ReplyChargingID>NoReplyChargingMessageID</ReplyChargingID>
                                         <Priority>Normal</Priority>
                                         <Subject>Subject</Subject>
                                         <Content href="/mms/mm7/mm7client" allowAdaptations="false" />
                                    </mm7:DeliverReq>
                               </soap-env:Body>
                          </soap-env:Envelope>
                          When set to UNQUALIFIED it fails on the subelements of <Recipients>...</Recipients>. The generated code of this element is shown in my previous post.
                          I feel your pain. This is the exact same problem that I had 9 years ago ( I thought it was 6 years ) which I also mentioned in the 3GPP mailing list since the example sections in the MM7 spec have all of the elements not having a namespace, which the carriers end up using. Forget about the namespaces, some of the ones I dealt with did not even have the elements which were required .. which leaves me to believe they were not really using an XML processor at their end, possibly having a template which they just do a search and replace, which is probably true because they have to deal with potentially several thousands of requests per second.

                          If I recall, in the end, frustrated, I ended up just parsing the XML and not validating it against the schema and using XPath to obtain the fields I needed.
                          • 10. Re: JAX-WS fails to unmarshal payload due to strict namespaces
                            726437
                            In the end I used a SoapHandler to rebuild the xml so that it is qualified. Not an optimal solution, and I wish there would be a more elegant solution to this. It just looks like CXF is simply to strict when it comes to namespaces and prefixes.