CXF client在并发下的线程安全问题2011-01-27 BlogJava sky ao这个是发生在上周周末的真实案例,因为cxf client 端线程安全导致的错误,总结出来希望其他使用cxf的兄弟注意。首先描述一下背景,简单的说就是使用cxf作为web service的客户端,运行在weblogic上,连接外部的服务器。为了测试需要,开发了一个简单的模拟器模拟服务器端,准备在release之前跑稳定性测试。结果出问题了,在排除掉一些干扰和诸如网络环境,设置等之后问题依旧,由于系统负责,包括ws的模拟器也是出了一个之前没有试过的方法,因此费了不少时间来查找问题。过程很枯燥,应该很多人经历过,在一个大的系统中找到一个小错误的出处,可以说是一门学问,技术耐心和运气都是需要的.....跳出这个过程,由于问题表现在web service的网络连接在这个异常上,在服务器端模拟器的日志中有大量的这种异常信息:2009-07-24 19:23:22,898 DEBUG ( : ) (tomcat-exec-56) [Http11NioProcessor] - Error parsing HTTP request header java.io.EOFException: Unexpected EOF read on the socket at org.apache.coyote.http11.InternalNioInputBuffer.readSocket(InternalNioInputBuffer.java:589) at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:425) at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:825) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2080) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619) 2009-07-24 19:23:22,898 DEBUG ( : ) (tomcat-exec-56) [Http11NioProcessor] - Error parsing HTTP request header java.io.EOFException: Unexpected EOF read on the socket at org.apache.coyote.http11.InternalNioInputBuffer.readSocket(InternalNioInputBuffer.java:589) at org.apache.coyote.http11.InternalNioInputBuffer.parseRequestLine(InternalNioInputBuffer.java:425) at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:825) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:719) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:2080) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619)而服务器端模拟器这次是我们第一次使用tomcat和coyote,因此怀疑是tomcat的问题,在再三追查代码无果的情况下,决定换一个服务器端模拟器来确认问题所在:到底是cxf的客户端的问题,还是服务器端模拟器。一个简单的模拟器写出来了,一个跳过所有业务逻辑直接调用cxf客户端实现代码的测试小程序写出来了,测试之后发现,问题依旧。于是将目光集中到cxf的客户端上。在测试中发现这样一个规律,在上述服务器端的异常发生前,在客户端中总是会有规律的出现下面这个异常:Jul 24, 2009 10:36:18 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept INFO: Interceptor has thrown exception, unwinding now null tps = 25 Exception in thread "Thread-41" 2009-07-24 22:36:19,925 149585 [Thread-41] (********Impl.java:459) ERROR junit.framework.Test - Got an exception when invoking **** service:javax.xml.ws.WebServiceException: java.lang.NullPointerException (这里的信息是和业务相关的,不方便打出,总之和我们讨论的问题无关) at test.TestMci.execute(TestMci.java:84) at test.TestMci.access$1(TestMci.java:81) at test.TestMci$TestThread.run(TestMci.java:90) at java.lang.Thread.run(Thread.java:595) Caused by: javax.xml.ws.WebServiceException: java.lang.NullPointerException at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:142) at $Proxy40.authorizeAndPurchase(Unknown Source) at ********************* 6 more Caused by: java.lang.NullPointerException at org.apache.cxf.transport.http.HTTPConduit.prepare(HTTPConduit.java:483) at org.apache.cxf.interceptor.MessageSenderInterceptor.handleMessage(MessageSenderInterceptor.java:46) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:226) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:469) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299) at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251) at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73) at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124) 8 more看来问题是出现在这里了。