Seth Leger created CXF-6463:
-------------------------------

             Summary: AbstractHTTPDestination.cacheInput() throws 
NullPointerException if HttpServletRequest returns null for getInputStream()
                 Key: CXF-6463
                 URL: https://issues.apache.org/jira/browse/CXF-6463
             Project: CXF
          Issue Type: Bug
          Components: JAX-RS
    Affects Versions: 3.1.1
            Reporter: Seth Leger


I am writing a unit test executing inside Spring 4.0's @WebApplicationContext 
unit test framework that invokes CXFServlet. Spring's framework provides a 
MockHttpServletRequest object that you can construct as input to a servlet 
request/response dispatch call.

If the incoming message body of the MockHttpServletRequest is empty, then when 
you call getInputStream() on it, MockHttpServletRequest will return null 
instead of returning a ServletInputStream that contains no data.

The code under the CXFServlet doesn't appear to like this behavior and crashes 
with a pretty mysterious stack trace:

{noformat}
2015-06-15 17:29:39,399 DEBUG [main] org.apache.cxf.phase.PhaseInterceptorChain 
- Invoking handleMessage on interceptor 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor@3118ed2c
2015-06-15 17:29:39,400 DEBUG [main] 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor - Response content type 
is: text/plain
2015-06-15 17:29:39,400 DEBUG [main] org.apache.cxf.ws.addressing.ContextUtils 
- retrieving MAPs from context property javax.xml.ws.addressing.context.inbound
2015-06-15 17:29:39,400 DEBUG [main] org.apache.cxf.ws.addressing.ContextUtils 
- WS-Addressing - failed to retrieve Message Addressing Properties from context
2015-06-15 17:29:39,401 ERROR [main] org.apache.cxf.jaxrs.utils.JAXRSUtils - 
Problem with writing the data, class java.lang.String, ContentType: text/plain
2015-06-15 17:29:39,402 DEBUG [main] org.apache.cxf.phase.PhaseInterceptorChain 
- Invoking handleFault on interceptor 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor@3118ed2c
2015-06-15 17:29:39,402 DEBUG [main] org.apache.cxf.phase.PhaseInterceptorChain 
- Invoking handleFault on interceptor 
org.apache.cxf.interceptor.MessageSenderInterceptor@1b6824c1
2015-06-15 17:29:39,403 WARN [main] org.apache.cxf.phase.PhaseInterceptorChain 
- Interceptor for {http://rest.web.opennms.org/}AcknowledgmentRestService has 
thrown exception, unwinding now
org.apache.cxf.interceptor.Fault
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:371)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:272)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:118)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:81)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at 
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:83)
        at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
        at 
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
        at 
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
        at 
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
        at 
org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
        at 
org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:293)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:217)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:735)
        at 
org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:268)
        at 
org.opennms.core.test.rest.AbstractSpringJerseyRestTestCase$1.doFilter(AbstractSpringJerseyRestTestCase.java:240)
        at 
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:232)
        at 
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at 
org.opennms.core.test.rest.AbstractSpringJerseyRestTestCase.dispatch(AbstractSpringJerseyRestTestCase.java:244)
        at 
org.opennms.core.test.rest.AbstractSpringJerseyRestTestCase.sendRequest(AbstractSpringJerseyRestTestCase.java:482)
        at 
org.opennms.core.test.rest.AbstractSpringJerseyRestTestCase.sendRequest(AbstractSpringJerseyRestTestCase.java:477)
        at 
org.opennms.core.test.rest.AbstractSpringJerseyRestTestCase.sendRequest(AbstractSpringJerseyRestTestCase.java:473)
        at 
org.opennms.web.rest.MinionRestServiceTest.testGetProperty(MinionRestServiceTest.java:116)
        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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at 
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at 
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at 
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at 
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
        at 
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
        at 
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
        at 
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
        at 
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
        at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at 
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at 
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at 
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
        at 
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at 
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
        at 
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:182)
        at org.apache.cxf.helpers.IOUtils.copy(IOUtils.java:141)
        at 
org.apache.cxf.io.DelegatingInputStream.cacheInput(DelegatingInputStream.java:54)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination$1.cacheInput(AbstractHTTPDestination.java:308)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.cacheInput(AbstractHTTPDestination.java:582)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.flushHeaders(AbstractHTTPDestination.java:604)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination.flushHeaders(AbstractHTTPDestination.java:597)
        at 
org.apache.cxf.transport.http.AbstractHTTPDestination$WrappedOutputStream.onFirstWrite(AbstractHTTPDestination.java:782)
        at 
org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
        at 
org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:60)
        at 
org.apache.cxf.jaxrs.provider.StringTextProvider.writeTo(StringTextProvider.java:72)
        at 
org.apache.cxf.jaxrs.provider.StringTextProvider.writeTo(StringTextProvider.java:35)
        at 
org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1375)
        at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:250)
        ... 53 more
{noformat}

If I subclass MockHttpServletRequest and have it return an empty 
ServletInputStream instead of null, then CXF works without throwing the NPE.

Just to be defensive, you might want to check for null return values from 
HttpServletRequest.getInputStream(). It seems like several people have run into 
issues with this, like this mailing list post:

http://mail-archives.apache.org/mod_mbox/cxf-users/201104.mbox/%[email protected]%3E



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to