Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

NumberFormatException leaks out through unmarshal #1211

@rwalkerands

Description

@rwalkerands

Environment:
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)

I think I'm experiencing a similar issue to what was reported against Jersey here:

http://download.oracle.com/javaee-archive/jersey.java.net/users/2010/01/9431.html
http://download.oracle.com/javaee-archive/jersey.java.net/users/2010/02/10038.html

To be specific: I'm using JAXB marshalling/unmarshalling of data using Jersey. The Java classes that describe the data are generated by xjc from an XML Schema.

If I invoke one of my API methods, where data is expected to be an int, but isn't (i.e., instead of providing an attribute upload-id="24" I provide upload-id="upload-id-goes-here"), I get back this stacktrace (from Tomcat):

HTTP Status 500 - java.lang.NumberFormatException: Not a number: upload-id-goes-here

type Exception report

message java.lang.NumberFormatException: Not a number: upload-id-goes-here

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException:
        java.lang.NumberFormatException: Not a number:
        upload-id-goes-here
        org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:487)
        org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
        net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:198)
        net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:176)
        au.org.ands.vocabs.registry.api.context.ApiOriginFilter.doFilter(ApiOriginFilter.java:73) 

root cause

java.lang.NumberFormatException: Not a number:
        upload-id-goes-here
        com.sun.xml.internal.bind.DatatypeConverterImpl._parseInt(DatatypeConverterImpl.java:110)
        com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$18.parse(RuntimeBuiltinLeafInfoImpl.java:725)
        com.sun.xml.internal.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$18.parse(RuntimeBuiltinLeafInfoImpl.java:723)
        com.sun.xml.internal.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.parse(TransducedAccessor.java:230)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:195)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
        com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
        com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
        com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:351)
        com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
        com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
        com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
        com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
        com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:841)
        com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
        com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
        com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
        com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
        com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
        javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
        javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
        org.glassfish.jersey.jaxb.internal.XmlRootElementJaxbProvider.readFrom(XmlRootElementJaxbProvider.java:140)
        org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:134)
        org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256)
        org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235)
        org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
        org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:74)
        org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
        org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
        org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
        org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271)
        org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.provide(EntityParamValueFactoryProvider.java:96)
        org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71)
        org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:94)
        org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127)
        org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:160)
        org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99)
        org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
        org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
        org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
        org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326)
        org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
        org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
        org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        org.glassfish.jersey.internal.Errors.process(Errors.java:267)
        org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
        org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
        org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
        org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:471)
        org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:425)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:383)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:336)
        org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:223)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108)
        net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:198)
        net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:176)
        au.org.ands.vocabs.registry.api.context.ApiOriginFilter.doFilter(ApiOriginFilter.java:73) 

note The full stack trace of the root cause is available in the Apache Tomcat/7.0.69 logs.
Apache Tomcat/7.0.69

It seems the AbstractUnmarshallerImpl.unmarshal() method leaks the NumberFormatException, rather than wrapping it in either an UnmarshalException or a JAXBException. Is this correct behaviour?

Jersey intercepts UnmarshalExceptions and wraps them as BadRequestExceptions, and I have defined a Jersey ExceptionMapper for BadRequestExceptions, which usually catches errors when parsing XML content provided as input to my API methods. But it isn't intercepting this particular exception.

I note that within com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl there are lots of places where various types of parse exceptions are wrapped as UnmarshalExceptions (using UnmarshallingContext.getInstance().handleError()). I am wondering if there should be (much?) more of this, e.g., the around the invocations of DatatypeConverterImpl._parseInt().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions