Spring Framework
  1. Spring Framework
  2. SPR-7696

Jaxb2 Unmarshalling fails when using spring-oxm-3.0.5 from springframework (with spring-oxm-1.5.9 from spring-ws it works)

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 3.0.5
    • Fix Version/s: None
    • Component/s: OXM
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      When Upgrading to Spring Framework version 3, we got an issue with our Spring WS Endpoints.
      Sometimes it would fail with the following exception:

      12:19:14.742 [12122157@qtp-3705235-0] DEBUG o.s.w.s.server.SoapMessageDispatcher - Endpoint invocation resulted in exception - responding with Fault
      java.lang.ArrayIndexOutOfBoundsException: -4
              at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startPrefixMapping(UnmarshallingContext.java:806) ~[jaxb-impl-2.2.1.jar:2.2.1]
              at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startPrefixMapping(InterningXmlVisitor.java:81) ~[jaxb-impl-2.2.1.jar:2.2.1]
              at com.sun.xml.bind.v2.runtime.unmarshaller.SAXConnector.startPrefixMapping(SAXConnector.java:116) ~[jaxb-impl-2.2.1.jar:2.2.1]
              at org.springframework.xml.stream.StaxStreamXmlReader.startPrefixMapping(StaxStreamXmlReader.java:170) ~[spring-xml-1.5.9.jar:1.5.9]
              at org.springframework.xml.stream.StaxStreamXmlReader.handleStartElement(StaxStreamXmlReader.java:145) ~[spring-xml-1.5.9.jar:1.5.9]
              at org.springframework.xml.stream.StaxStreamXmlReader.parseInternal(StaxStreamXmlReader.java:80) ~[spring-xml-1.5.9.jar:1.5.9]
              at org.springframework.xml.stream.AbstractStaxXmlReader.parse(AbstractStaxXmlReader.java:128) ~[spring-xml-1.5.9.jar:1.5.9]
              at org.springframework.xml.stream.AbstractStaxXmlReader.parse(AbstractStaxXmlReader.java:111) ~[spring-xml-1.5.9.jar:1.5.9]
              at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:211) ~[jaxb-impl-2.2.1.jar:2.2.1]
              at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:184) ~[jaxb-impl-2.2.1.jar:2.2.1]
              at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:119) ~[jaxb-api-2.2.1.jar:na]
              at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:102) ~[jaxb-api-2.2.1.jar:na]
              at org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:581) ~[spring-oxm-3.0.5.RELEASE.jar:3.0.5.RELEASE]
              at org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62) ~[spring-ws-core-1.5.9.jar:1.5.9]
              at org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter.unmarshalRequest(MarshallingMethodEndpointAdapter.java:143) ~[spring-ws-core-1.5.9.jar:1.5.9]
              at org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter.invokeInternal(MarshallingMethodEndpointAdapter.java:134) ~[spring-ws-core-1.5.9.jar:1.5.9]
              at org.springframework.ws.server.endpoint.adapter.AbstractMethodEndpointAdapter.invoke(AbstractMethodEndpointAdapter.java:58) ~[spring-ws-core-1.5.9.jar:1.5.9]
              at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:228) [spring-ws-core-1.5.9.jar:1.5.9]
      ...
      

      I noticed that my classpath would contain two versions of spring-oxm, one from spring-ws, and one from springframework. If I rearranged my dependencies, and made sure that only the old one from spring-ws was present on my classpath, all requests would work again. So there seems to be a problem introduced into spring-oxm when it was moved into springframework.

      I have created a complete maven project that will recreate this issue. The pom.xml included contains two profiles

      • spring-oxm-from-springframework
        • is active by default
        • defines dependency to spring-oxm-3.0.5.RELEASE (and excludes spring-oxm from spring-ws)
      • spring-oxm-from-springws
        • can be triggered with property -Dx
        • defines dependency to spring-oxm-1.5.9

      Invoking mvn clean test (spring-oxm-from-springframework profile) on the project will fail one of the tests, while invoking it with the other profile mvn clean test -Dx (spring-oxm-from-springws) passes both tests

      The difference between the two tests is different input payload xmls. (see src/test/resources/ for input xmls)
      The content is identical, however on the different xml files, the namespace declarations are defined in the root element in one file, and on every element on the other file.

      Content from xml files included below:

      fails.xml
       
      <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
         <Body xmlns="http://schemas.xmlsoap.org/soap/envelope/">
            <SaveForecastsRequest xmlns="urn://schemas/message/TradeService/1">
               <ForecastList xmlns="urn://schemas/message/TradeService/1">
                  <Forecasts xmlns="urn://schemas/message/TradeService/1">
                     <Version xmlns="urn://schemas/data/DomainObjectType/1">1</Version>
                     <CreatedBy xmlns="urn://schemas/data/DomainObjectType/1">user</CreatedBy>
                     <CreatedWhen xmlns="urn://schemas/data/DomainObjectType/1">0001-01-01T00:00:00</CreatedWhen>
                     <Active xmlns="urn://schemas/data/DomainObjectType/1">false</Active>
                     <Forecast xmlns="urn://schemas/data/Trade/1">
                        <Value xmlns="urn://schemas/data/ValueWithUnit/1">10</Value>
                        <UnitId xmlns="urn://schemas/data/ValueWithUnit/1">KWH</UnitId>
                     </Forecast>
                  </Forecasts>
               </ForecastList>
            </SaveForecastsRequest>
         </Body>
      </Envelope>
      
      works.xml
       
      <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
         <s:Body>
            <message:SaveForecastsRequest 
            xmlns:message="urn://schemas/message/TradeService/1"
            xmlns:trade="urn://schemas/data/Trade/1"
            xmlns:value="urn://schemas/data/ValueWithUnit/1"
            xmlns:domainObject="urn://schemas/data/DomainObjectType/1">
               <message:ForecastList>
                  <message:Forecasts>
                     <domainObject:Version>1</domainObject:Version>
                     <domainObject:CreatedBy>user</domainObject:CreatedBy>
                     <domainObject:CreatedWhen>0001-01-01T00:00:00</domainObject:CreatedWhen>
                     <domainObject:Active>false</domainObject:Active>
                     <trade:Forecast>
                        <value:Value>10</value:Value>
                        <value:UnitId>KWH</value:UnitId>
                     </trade:Forecast>
                  </message:Forecasts>
               </message:ForecastList>
            </message:SaveForecastsRequest>
         </s:Body>
      </s:Envelope> 
      

      Both xml files are well-formed and valid according to the xsd's (src/main/resources/data, src/main/resource/message)

      (Interesting sidenote, if I enable payload validation with the org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor, both profiles will fail the one test using fails.xml. Just change the validateRequest property of that bean declaration in src/main/resources/ws.xml to true. Now the test will fail with another stacktrace - similar in nature, but originating from inside xerces...)

        Activity

        Hide
        Paul Nyheim added a comment -

        I have also reproduced this issue with dependencies to the Spring WS 2.0.0-M3 release, and would consider this a regression against Spring WS, as this was working under 1.5.9.

        Show
        Paul Nyheim added a comment - I have also reproduced this issue with dependencies to the Spring WS 2.0.0-M3 release, and would consider this a regression against Spring WS, as this was working under 1.5.9.
        Hide
        Arjen Poutsma added a comment -

        If I understand the issue correctly, you are trying to use the Spring 3.0 OXM jars together with Spring-WS 1.5. This is not supported: Spring-WS 1.5 only works with the Spring-WS 1.5 OXM jars. Spring-WS 2.0 will work with the Spring 3.0 OXM jars, as it will not have its own OXM anymore.

        I've updated your sample to use Spring-WS 2.0 M4 and Spring OXM 3.0, and then it works fine.

        Show
        Arjen Poutsma added a comment - If I understand the issue correctly, you are trying to use the Spring 3.0 OXM jars together with Spring-WS 1.5. This is not supported: Spring-WS 1.5 only works with the Spring-WS 1.5 OXM jars. Spring-WS 2.0 will work with the Spring 3.0 OXM jars, as it will not have its own OXM anymore. I've updated your sample to use Spring-WS 2.0 M4 and Spring OXM 3.0, and then it works fine.

          People

          • Assignee:
            Arjen Poutsma
            Reporter:
            Paul Nyheim
            Last updater:
            Trevor Marshall
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              3 years, 24 weeks, 3 days ago