Details
-
Bug
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
servicemix-cxf-se-2010.01
-
None
-
Servicemix 3.3.2
Description
The servicemix-cxf-se component gets a NullPointerException (see below) whenever using
a one-way message exchange pattern, where the method invoked calls a proxy.
Diagnosis: internally cxf is using the org.apache.cxf.interceptor.OneWayProcessorInterceptor
class to intercept a one-way method invocation and perform that invocation on
a separate thread. The servicemix-cxf-se method handler is depending on being called
with enough thread context that it can contact other JBI endpoints, but gets an
NPE because the endpoint cannot be located.
Workaround: after digging around, found that the OneWayProcessorInterceptor
allows invocation inline with the caller's thread, which in this case is
the servicemix-cxf-se CxfSeEndpoint.process method which sets up delivery channel
and other thread-local data. If the property:
org.apache.cxf.interceptor.OneWayProcessorInterceptor.USE_ORIGINAL_THREAD
is set to true on the bus, or on the message exchange (among others), the
one-way interceptor will just not process the method. This fixes the issue.
The workaround in xbean.xml deployment is to do the following:
<cxf:bus>
<cxf:properties>
<entry key="org.apache.cxf.interceptor.OneWayProcessorInterceptor.USE_ORIGINAL_THREAD" value="true"/>
</cxf:properties>
</cxf:bus>
Obviously, this should not be a requirement to workaround this because it
took a few hours of source-level debugging through cxf and servicemix to
find this workaround.
Note: my usecase is to use the servicemix-quartz component which can only
call one-way MEPs. I did reproduce this problem with servicemix-cxf-bc
and servicemix-cxf-se so it's not a servicemix-quartz issue.
Here's the stacktrace of the failure:
NOTE: the commitOutputMessage catch of RuntimeException is evil here
in not chaining the original exception, but that is a bug in
cxf, not servicemix or servicemix-cxf-se
java.lang.RuntimeException: java.lang.NullPointerException
at org.apache.cxf.transport.jbi.JBIConduitOutputStream.commitOutputMessage(JBIConduitOutputStream.java:202)
at org.apache.cxf.transport.jbi.JBIConduitOutputStream.doClose(JBIConduitOutputStream.java:81)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:185)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:66)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:484)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:310)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:262)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
at $Proxy110.getScheduledCommunities(Unknown Source)
at com.novell.soa.ccm.scheduler.TriggerPortImpl.fireTriggerOperation(TriggerPortImpl.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89)
at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:60)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:75)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243)
at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:218)
at org.apache.cxf.interceptor.OneWayProcessorInterceptor$1.run(OneWayProcessorInterceptor.java:100)
at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$2.run(AutomaticWorkQueueImpl.java:253)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)