PAX 考试集成测试 REST 客户端调用 REST 服务失败,原因为:java.net.SocketTimeoutException:读取超时

PAX Exam integration test REST client call to REST service fails with Caused by: java.net.SocketTimeoutException: Read timed out

我有一个集成测试,将休息客户端注入测试 class。当该休息客户端调用由同一个 pax 考试测试容器托管的休息服务时,一切都会停止大约一分钟,直到我得到一长串套接字读取超时异常和连接拒绝异常。如果我注入一个在另一个容器中调用休息服务的休息客户端,一切正常。似乎没有为其余服务提供执行线程。如果我手动启动 pax 考试容器,我可以验证其余服务是否已正确启动。如果我将 OSGi 服务注入测试 class 一切正常。使用 PaxExam 3.6 和 Apache ServiceMix (4.5.3)

堆栈跟踪:

2015-04-22 17:10:02,211 | WARN  | ion(1)-127.0.0.1 | PhaseInterceptorChain            | 123 - org.apache.cxf.cxf-api - 2.6.6 | Interceptor for {http://rest.mediation.velocity.randomness.com/}mediationService has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)[123:org.apache.cxf.cxf-api:2.6.6]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)[123:org.apache.cxf.cxf-api:2.6.6]
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.doChainedInvocation(ClientProxyImpl.java:530)[139:org.apache.cxf.cxf-rt-frontend-jaxrs:2.6.6]
    at org.apache.cxf.jaxrs.client.ClientProxyImpl.invoke(ClientProxyImpl.java:205)[139:org.apache.cxf.cxf-rt-frontend-jaxrs:2.6.6]
    at com.sun.proxy.$Proxy156.getmediations(Unknown Source)
    at com.randomness.velocity.mediation.rest.client.mediationClient.getmediations(mediationClient.java:90)[282:mediation-rest-client:3.1.0.SNAPSHOT]
    at com.randomness.velocity.mediation.rest.client.mediationClient.getmediations(mediationClient.java:97)[282:mediation-rest-client:3.1.0.SNAPSHOT]
    at com.randomness.velocity.itest.client_management.DataCleanupTests.verifyvelocityClientManagementStarts(DataCleanupTests.java:123)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_75]
    at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_75]
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:67)
    at org.ops4j.pax.exam.invoker.junit.internal.ContainerTestRunner.runChild(ContainerTestRunner.java:37)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:53)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.junit.runner.JUnitCore.run(JUnitCore.java:138)[313:org.ops4j.pax.tipi.junit:4.11.0.1]
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.invokeViaJUnit(JUnitProbeInvoker.java:124)
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.findAndInvoke(JUnitProbeInvoker.java:97)
    at org.ops4j.pax.exam.invoker.junit.internal.JUnitProbeInvoker.call(JUnitProbeInvoker.java:73)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_75]
    at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_75]
    at org.ops4j.pax.exam.rbc.internal.RemoteBundleContextImpl.remoteCall(RemoteBundleContextImpl.java:80)[311:org.ops4j.pax.exam.rbc:3.6.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.7.0_75]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)[:1.7.0_75]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.7.0_75]
    at java.lang.reflect.Method.invoke(Method.java:606)[:1.7.0_75]
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)[:1.7.0_75]
    at sun.rmi.transport.Transport.run(Transport.java:202)[:1.7.0_75]
    at sun.rmi.transport.Transport.run(Transport.java:199)[:1.7.0_75]
    at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_75]
    at sun.rmi.transport.Transport.serviceCall(Transport.java:198)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:567)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.access0(TCPTransport.java:619)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:684)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)[:1.7.0_75]
    at java.security.AccessController.doPrivileged(Native Method)[:1.7.0_75]
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:681)[:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)[:1.7.0_75]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)[:1.7.0_75]
    at java.lang.Thread.run(Thread.java:745)[:1.7.0_75]
Caused by: java.net.SocketTimeoutException: SocketTimeoutException invoking https://127.0.0.1:7103/mediation/patient/ff8081814ce1299a014ce142cb410065?materialization=Full: Read timed out
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)[:1.7.0_75]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)[:1.7.0_75]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)[:1.7.0_75]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)[:1.7.0_75]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1469)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1454)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)[123:org.apache.cxf.cxf-api:2.6.6]
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:659)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)[123:org.apache.cxf.cxf-api:2.6.6]
    ... 54 more
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)[:1.7.0_75]
    at java.net.SocketInputStream.read(SocketInputStream.java:152)[:1.7.0_75]
    at java.net.SocketInputStream.read(SocketInputStream.java:122)[:1.7.0_75]
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)[:1.7.0_75]
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)[:1.7.0_75]
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)[:1.7.0_75]
    at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:891)[:1.7.0_75]
    at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)[:1.7.0_75]
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)[:1.7.0_75]
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)[:1.7.0_75]
    at java.io.BufferedInputStream.read(BufferedInputStream.java:334)[:1.7.0_75]
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)[:1.7.0_75]
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:633)[:1.7.0_75]
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1324)[:1.7.0_75]
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)[:1.7.0_75]
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)[:1.7.0_75]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1606)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1532)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1440)[135:org.apache.cxf.cxf-rt-transports-http:2.6.6]

我明白是怎么回事了。我在集成测试项目中将 osgi:service 添加到 spring 配置,将其余客户端公开为 osgi 服务,因此我可以将客户端注入测试 class。通过这样做,我在 osgi 容器中创建了第二个服务,该服务通过其余服务用来查找真正的 osgi 服务实现的相同接口进行广告。所以 rest 服务实际上是将 rest 客户端而不是 osgi 服务 impl 注入其中,这创建了一个无限循环,最终崩溃并向我的控制台抛出大量连接被拒绝和套接字读取超时异常。好东西