Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-6758

DataReaderImpl.handleEvent is too strict in case of XMLGregorianCalendar parse error of severity ValidationEvent.ERROR

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Not A Problem
    • 3.1.4
    • Invalid
    • None
    • None
    • CXF 3.1.4 integrated into JBoss Wildly 10.0.0.CR5, java version 1.8.0_71

    • Unknown

    Description

      The implementation of org.apache.cxf.jaxb.io.DataReaderImpl.handleEvent(ValidationEvent event) is too strict in comparison to com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleEvent(ValidationEvent) and returns false (cannot recover) if the ValidationEvent.severity equals ValidationEvent.ERROR.

      In the following, details from a real-world Web service where we have encountered this issue.

      The issue can be observed when invoking the method GetListModel of this Web service whose reply message contains elements of the complex type ETGdateType that contains a field of type xsd:gMonth (and xsd:gYear). The following is an excerpt of the relevant part of a reply message:

      <ProductionStartDate xsi:type="ns1:ETGdateType">
        <Month xsi:type="xsd:gMonth">07</Month>
        <Year xsi:type="xsd:gYear">2010</Year>
      </ProductionStartDate>
      

      If invoked by a service client class from within a Web application deployed to Wildfly (which uses CXF), an unmarshalling error occurs and the following stack trace is logged:

      16:43:46,891 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (default task-113) Interceptor for {http://www.eurotax.com/Webservices/Identification/}IdentificationStub#{http://www.eurotax.com/Webservices/Identification/}GetListModel has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Unmarshalling Error: 07 
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:905)
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:712)
      	at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:179)
      	at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:109)
      	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
      	at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1669)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1550)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1347)
      	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
      	at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651)
      	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
      	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
      	at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
      	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
      	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
      	at com.sun.proxy.$Proxy147.getListModel(Unknown Source)
      	at ch.sbi.forte.ws.client.etg.IdentificationServiceImpl.getListModel(IdentificationServiceImpl.java:277)
      	at ch.sbi.forte.services.rest.CarInsuranceResource.getListModel(CarInsuranceResource.java:302)
      	at ch.sbi.forte.services.rest.CarInsuranceResource$Proxy$_$$_WeldClientProxy.getListModel(Unknown Source)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:497)
      	at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)
      	at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
      	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
      	at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236)
      	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:395)
      	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:202)
      	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
      	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
      	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
      	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
      	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
      	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
      	at ch.sbi.atlas.servlet.filter.ResponseHeaderFilter.doFilter(ResponseHeaderFilter.java:110)
      	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
      	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
      	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
      	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
      	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
      	at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at org.keycloak.adapters.undertow.UndertowAuthenticatedActionsHandler.handleRequest(UndertowAuthenticatedActionsHandler.java:66)
      	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
      	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
      	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
      	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
      	at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
      	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
      	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
      	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
      	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at org.keycloak.adapters.undertow.ServletPreAuthActionsHandler.handleRequest(ServletPreAuthActionsHandler.java:69)
      	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
      	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
      	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
      	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
      	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
      	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
      	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      	at java.lang.Thread.run(Thread.java:745)
      Caused by: javax.xml.bind.UnmarshalException
       - with linked exception:
      [com.sun.istack.SAXParseException2; lineNumber: 0; columnNumber: 0; 07]
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:483)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:394)
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:855)
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:102)
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder$2.run(JAXBEncoderDecoder.java:894)
      	at java.security.AccessController.doPrivileged(Native Method)
      	at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:892)
      	... 72 more
      Caused by: com.sun.istack.SAXParseException2; lineNumber: 0; columnNumber: 0; 07
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:740)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:770)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:766)
      	at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$12.parse(RuntimeBuiltinLeafInfoImpl.java:595)
      	at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$12.parse(RuntimeBuiltinLeafInfoImpl.java:568)
      	at com.sun.xml.bind.v2.runtime.FilterTransducer.parse(FilterTransducer.java:84)
      	at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.parse(TransducedAccessor.java:245)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.LeafPropertyLoader.text(LeafPropertyLoader.java:65)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.text(UnmarshallingContext.java:589)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.InterningXmlVisitor.text(InterningXmlVisitor.java:93)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.processText(StAXStreamConnector.java:338)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleEndElement(StAXStreamConnector.java:216)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:185)
      	at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:415)
      	... 78 more
      Caused by: javax.xml.bind.UnmarshalException: 07
       - with linked exception:
      [java.lang.IllegalArgumentException: 07]
      	... 92 more
      Caused by: java.lang.IllegalArgumentException: 07
      	at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parseYear(XMLGregorianCalendarImpl.java:2952)
      	at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl$Parser.parse(XMLGregorianCalendarImpl.java:2862)
      	at org.apache.xerces.jaxp.datatype.XMLGregorianCalendarImpl.<init>(XMLGregorianCalendarImpl.java:478)
      	at org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl.newXMLGregorianCalendar(DatatypeFactoryImpl.java:230)
      	at __redirected.__DatatypeFactory.newXMLGregorianCalendar(__DatatypeFactory.java:180)
      	at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$12.parse(RuntimeBuiltinLeafInfoImpl.java:592)
      	... 88 more
      

      This is due to the following code in org.apache.cxf.jaxb.io.DataReaderImpl.WSUIDValidationHandler.handleEvent(ValidationEvent), line 71 to 86 as released for version 3.1.4 for CXF:

              public boolean handleEvent(ValidationEvent event) {
                  // if the original handler has already handled the event, no need for us
                  // to do anything, otherwise if not yet handled, then do this 'hack' 
                  if (origHandler != null && origHandler.handleEvent(event)) {
                      return true;
                  } else {
                      // hack for CXF-3453
                      String msg = event.getMessage();
                      return msg != null 
                          && msg.contains(":Id") 
                          && (msg.startsWith("cvc-type.3.1.1: ") 
                              || msg.startsWith("cvc-type.3.2.2: ") 
                              || msg.startsWith("cvc-complex-type.3.1.1: ")
                              || msg.startsWith("cvc-complex-type.3.2.2: "));
                  }
              }
      

      At runtime, while debugging, origHandler is null, msg equals 07, and event.severity is 1, the latter of which will become relevant in a second. Hence, this method returns false, which ultimately leads to aborting parsing the reply further above in the stack.

      In contrast, invoking the same Web service method in Glassfish 4 works (same Web service method, same Java client stubs generated using same version of wsimport). This has also been debugged in detail. Interestingly, also in Glassfish parsing of the xsd:gMonth value '07' leads to an IllegalArgumentException in XMLGregorianCalendarImpl (though the implementation that is actually used in this case is com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl). Also, there is a ValidationEvent object created and its severity is 1 (ValidationEvent.ERROR). However, another ValidationEventHandler implementation is used in this case, which is com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleEvent(ValidationEvent), the source code being:

          public boolean handleEvent(ValidationEvent event) {
              return event.getSeverity()!=ValidationEvent.FATAL_ERROR;
          }
      

      As can be seen, every event whose severity is not a FATAL_ERROR results in returning true (recoverable), which explains why the invocation works with Glassfish.

      I'm not an expert on lexical representations of XSD types, and in particular, I do not know whether the string '07' is a syntactically correct representation of a xsd:gMonth, but I think also CXF should handle this parse error as recoverable; i.e., return true from handleEvent as the reference implementation does. More importantly, I think this issue should be fixed somehow such that invoking the Web service does not abort when the reply is parsed.

      Attachments

        Activity

          People

            dkulp Daniel Kulp
            twwwt Thorsten Möller
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: