在 Java 中使用 CXF 生成的存根调试 SOAP 网络服务调用为某些人提供了 SSL 异常

Debugging SOAP webservice calls using CXF generated stubs in Java gives SSL Exceptions for some people

我们有一个项目设置,我们使用 CXF 生成的存根调用外部 SOAP 网络服务。 SOAP 调用使用基于证书的安全性。除了调试代码(我们使用 IntelliJ)之外,这一切都完美无缺。

当 运行 代码有效时。在调试和断点到断点运行时,它起作用了。当逐步调试并主动进入或跳过调用 SOAP 服务的方法时,某些人会出现以下错误(我编辑了一些 class 和方法名称):

javax.xml.ws.WebServiceException: Could not send Message.
    at org.apache.cxf.jaxws.JaxWsClientProxy.mapException(JaxWsClientProxy.java:183)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145)
    at com.sun.proxy.$Proxy91.getData(Unknown Source)
    at com.mycompany.batch.service.MyService.getData(MyService.java:763)
    at com.mycompany.proxy.MyProxy.getData(MyProxy.java:152)
    at com.mycompany.model.MyAction.updateDossier(MyAction.java:91)
    at com.mycompany.model.MyAction.process(MyAction.java:80)
    at com.mycompany.model.AbstractAction.process(AbstractAction.java:68)
    at com.mycompany.MyTestCase.main(MyTestCase.java:33)
Caused by: javax.net.ssl.SSLException: SSLException invoking https://someexternalurl.com/v6: readHandshakeRecord
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1402)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1386)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:228)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:673)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:63)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:440)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:355)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:313)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
    ... 10 more
Caused by: javax.net.ssl.SSLException: readHandshakeRecord
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1072)
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
    at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
    at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1356)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1331)
    at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:241)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:274)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1345)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1306)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:307)
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1358)
    ... 22 more
Caused by: java.net.SocketException: Connection reset by peer: socket write error
    at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
    at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
    at java.base/sun.security.ssl.SSLSocketOutputRecord.flush(SSLSocketOutputRecord.java:251)
    at java.base/sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:89)
    at java.base/sun.security.ssl.CertificateVerify$T12CertificateVerifyProducer.produce(CertificateVerify.java:749)
    at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
    at java.base/sun.security.ssl.ServerHelloDone$ServerHelloDoneConsumer.consume(ServerHelloDone.java:173)
    at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:444)
    at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:421)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:178)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1152)
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1063)
    ... 35 more

我们是一个由多个开发人员组成的团队,大约 50% 的人遇到过这个问题,而其他人则没有也根本无法重现这个问题。

因为它只在调试时发生,所以可能是 IntelliJ 如何进行实际调试的问题。

我找到了这个帖子:Server-side handling missing client connection (reset by peer)?

它提到一个客户端线程挂起服务器,但没有给出进一步的信息。

有人知道问题出在哪里吗?

编辑:我们尝试并排调试相同的代码并通过调试信息比较所有设置。我们检查的所有内容(而且我们检查了很多)完全相同。

我们做了很多额外的研究,也使用了 Wireshark,我们看到了 RST,但找不到解决方案。

直到我们看到工作机器使用 JDK 11.0.5 而故障机器使用 JDK 11.0.2。升级到 11.0.5+ (11.0.14) 解决了我们的问题。 JDK 颠覆中的具体修复或更改仍然未知。