You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Jim Talbut <jt...@spudsoft.co.uk> on 2013/11/29 10:04:18 UTC

Exception when using two separate Spring contexts both using Jackson

Hi,

In my JUnit tests I have two Spring-based tests that declare JAX-RS 
providers (on different local ports) like:

     <bean id="jsonProvider" 
class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider">
     </bean>
     <bean id="securityExceptionMapper" 
class="uk.co.spudsoft.spiderweborders.process.security.SecurityExceptionMapper" 
/>
     <bean id="htmlProvider" 
class="uk.co.spudsoft.spiderweborders.api.service.HtmlProvider" >
         <property name="htmlContentResource" value="/resource.html" />
     </bean>
     <bean id="illegalArgumentExceptionMapper" 
class="uk.co.spudsoft.spiderweborders.api.service.IllegalArgumentExceptionMapper" 
/>
     <bean id="catchAllExceptionMapper" 
class="uk.co.spudsoft.spiderweborders.api.service.CatchAllExceptionMapper" 
/>

     <bean id="exceptionResource" 
class="uk.co.spudsoft.test.rest.ExceptionResource" />

     <jaxrs:server id="restServer" address="http://0.0.0.0:9281/rest/" >
         <jaxrs:serviceBeans>
             ...
         </jaxrs:serviceBeans>
         <jaxrs:providers>
             <ref bean="htmlProvider" />
             <ref bean="jsonProvider" />
             <bean 
class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider" />
             <ref bean="securityExceptionMapper" />
             <ref bean="illegalArgumentExceptionMapper" />
             <ref bean="catchAllExceptionMapper" />
         </jaxrs:providers>
     </jaxrs:server>

The tests both work when run independently, but when I run them both 
together (which will mean Spring keeps the contexts around after the 
test finishes) I get this error:
08:58:12.285 [qtp842577946-28] ERROR u.c.s.s.a.s.CatchAllExceptionMapper 
- Exception caught:
java.lang.NullPointerException: null
     at 
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50) 
~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
     at 
com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider._locateMapperViaProvider(JacksonJsonProvider.java:203) 
~[jackson-jaxrs-json-provider-2.3.0.jar:2.3.0]
     at 
com.fasterxml.jackson.jaxrs.base.ProviderBase.locateMapper(ProviderBase.java:817) 
~[jackson-jaxrs-base-2.3.0.jar:2.3.0]
     at 
com.fasterxml.jackson.jaxrs.base.ProviderBase.writeTo(ProviderBase.java:563) 
~[jackson-jaxrs-base-2.3.0.jar:2.3.0]
     at 
org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1317) 
~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:282) 
[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155) 
[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86) 
[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272) 
[cxf-api-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77) 
[cxf-api-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272) 
[cxf-api-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) 
[cxf-api-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355) 
[cxf-rt-transports-http-jetty-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319) 
[cxf-rt-transports-http-jetty-2.7.7.jar:2.7.7]
     at 
org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72) 
[cxf-rt-transports-http-jetty-2.7.7.jar:2.7.7]
     at 
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:195) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at org.eclipse.jetty.server.Server.handle(Server.java:370) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644) 
[jetty-http-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235) 
[jetty-http-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82) 
[jetty-server-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668) 
[jetty-io-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52) 
[jetty-io-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608) 
[jetty-util-8.1.12.v20130726.jar:8.1.12.v20130726]
     at 
org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543) 
[jetty-util-8.1.12.v20130726.jar:8.1.12.v20130726]
     at java.lang.Thread.run(Thread.java:724) [na:1.7.0_40]

Can anyone shed any light on this?

I can't use "@DirtiesContext" after all of my tests because it would 
take too long to build the contexts, but I'm quite happy to change my 
config if that'll get rid of the problem.

Thanks

Jim


Re: Exception when using two separate Spring contexts both using Jackson

Posted by Jim Talbut <jt...@spudsoft.co.uk>.
On 29/11/2013 11:12, Sergey Beryozkin wrote:
> Hi Jim,
>
> Thanks for the update,
>
> I was concerned about
>
>  >> java.lang.NullPointerException: null
>  >>      at
>  >>
> org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)
>
>
> should we still investigate it ? I'm just not exactly sure how a thread
> local cache can be affected such that NPE is thrown, even though there
> were issues with Bus references before your fix.
>
> May the following sequence can explain: the thread creates a context,
> two tests are started, the thread finishes one test, clears a context,
> and now finishes the 2nd test, but the context has gone. This can
> explain it. If you think it does not then please create a test project
> for me to investigate it further
>
> Thanks, Sergey
>
It has to be something like that, but I'm not sure what Spring/JUnit/CXF 
would have cleared.
The other thing that still confuses me is that I would have expected the 
BusFactory.setDefault to affect things on the thread on which it is run, 
but the exception comes from the server thread (which should have an 
independent bus).

Anyway, I'm happy that the fix works and, whilst I think it would be 
good for you to document any limitation here, I can't quite think how 
you could have done that in a way that I would have found - so the 
existence of this email thread is probably as good as anything.

If I get the chance I will produce a test case, but it's not a priority.

Thanks.

Jim

Re: Exception when using two separate Spring contexts both using Jackson

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Jim,

Thanks for the update,

I was concerned about

 >> java.lang.NullPointerException: null
 >>      at
 >> 
org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50) 


should we still investigate it ? I'm just not exactly sure how a thread 
local cache can be affected such that NPE is thrown, even though there 
were issues with Bus references before your fix.

May the following sequence can explain: the thread creates a context, 
two tests are started, the thread finishes one test, clears a context, 
and now finishes the 2nd test, but the context has gone. This can 
explain it. If you think it does not then please create a test project 
for me to investigate it further

Thanks, Sergey

On 29/11/13 10:55, Jim Talbut wrote:
> On 29/11/2013 09:04, Jim Talbut wrote:
>> Hi,
>>
>> In my JUnit tests I have two Spring-based tests that declare JAX-RS
>> providers (on different local ports)
>>
>> The tests both work when run independently, but when I run them both
>> together (which will mean Spring keeps the contexts around after the
>> test finishes) I get this error:
>> 08:58:12.285 [qtp842577946-28] ERROR u.c.s.s.a.s.CatchAllExceptionMapper
>> - Exception caught:
>> java.lang.NullPointerException: null
>>      at
>> org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)
>>
>> ~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
>>      at
>> com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider._locateMapperViaProvider(JacksonJsonProvider.java:203)
>>
>
> Ahah!
>
> Why do I always spend ages looking for a solution then find it soon
> after mailing this group? :)
> I found the answer courtesy of this:
> http://camel.465427.n5.nabble.com/Problem-using-unit-test-spring-cxf-td5725603.html
>
>
> In my case clearing the bus worked sometimes, but some tests still
> failed, so I set it to the correct bus too.
> Putting the following in the base class that all the tests derive from
> makes the problem go away:
>
>      @Autowired
>      protected Bus cxf;
>
>      @Before
>      public void prepare() {
>          BusFactory.setDefaultBus(cxf);
>      }
>
>      @After
>      public void cleanup() {
>          BusFactory.setDefaultBus(null);
>      }
>
> Jim
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: Exception when using two separate Spring contexts both using Jackson

Posted by Jim Talbut <jt...@spudsoft.co.uk>.
On 29/11/2013 09:04, Jim Talbut wrote:
> Hi,
>
> In my JUnit tests I have two Spring-based tests that declare JAX-RS
> providers (on different local ports)
>
> The tests both work when run independently, but when I run them both
> together (which will mean Spring keeps the contexts around after the
> test finishes) I get this error:
> 08:58:12.285 [qtp842577946-28] ERROR u.c.s.s.a.s.CatchAllExceptionMapper
> - Exception caught:
> java.lang.NullPointerException: null
>      at
> org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)
> ~[cxf-rt-frontend-jaxrs-2.7.7.jar:2.7.7]
>      at
> com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider._locateMapperViaProvider(JacksonJsonProvider.java:203)

Ahah!

Why do I always spend ages looking for a solution then find it soon 
after mailing this group? :)
I found the answer courtesy of this: 
http://camel.465427.n5.nabble.com/Problem-using-unit-test-spring-cxf-td5725603.html

In my case clearing the bus worked sometimes, but some tests still 
failed, so I set it to the correct bus too.
Putting the following in the base class that all the tests derive from 
makes the problem go away:

     @Autowired
     protected Bus cxf;

     @Before
     public void prepare() {
         BusFactory.setDefaultBus(cxf);
     }

     @After
     public void cleanup() {
         BusFactory.setDefaultBus(null);
     }

Jim