java - CentOS 4 上 Java 1.6 的相当神秘的 SocketException

标签 java networking

我有一个 JAX-RS 网络服务的 JUnit 测试。该测试启动嵌入式 tomcat,然后通过 Apache CXF JAX-RS 客户端与其对话。

考虑这个回溯:

Caused by: java.net.SocketException: Socket Closed
        at java.net.PlainSocketImpl.getOption(PlainSocketImpl.java:286)
        at java.net.Socket.getSoTimeout(Socket.java:1032)
        at sun.net.www.http.HttpClient.available(HttpClient.java:356)
        at sun.net.www.http.HttpClient.New(HttpClient.java:273)
        at sun.net.www.http.HttpClient.New(HttpClient.java:310)
        at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:987)
        at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:923)
        at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:841)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1031)

在 CentOS 4.8 上失败。相同的单元测试(启动嵌入式 tomcat,然后与其中的 Web 服务对话)在各种其他系统上工作得很好。请注意此回溯的极端古怪:HttpHRLConnection已调用HttpClient获得一个新的连接,并且后面的类显然在连接返回之前关闭了它自己的套接字,我的任何代码都可以到达它。

此外,测试中有 friend 对相同的服务进行相同的服务器设置,并且可以毫无问题地与之对话。

更进一步,以下咒语(略有缩写)是一种解决方法:

@Before
public void pingServiceToWorkAroundCentos() {
   try {
      /* ... code to make a connection to the service and close it ... */
   } catch (Throwable t) {
      // do nothing
   }
}

换句话说,如果我在运行每个测试用例之前安排一个额外的一次性连接,那么无论这个问题是什么,它都会用完。

这会是什么?

最佳答案

由于这里只有回溯而没有代码,我假设存在某种竞争条件或错误,在当前线程尝试获取 OutputStream 时套接字被另一个线程先于关闭。

查看 JDK 的源代码,我看到了这个...

public Object getOption(int opt) throws SocketException {
    if (isClosedOrPending()) {
        throw new SocketException("Socket Closed");
    }
    ... snip ...

isClosedOrPending 方法检查内部 FD 是否为 null 或关闭是否挂起,即已在套接字上调用关闭。

祝你好运。

关于java - CentOS 4 上 Java 1.6 的相当神秘的 SocketException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14270311/

相关文章:

java - HttpMessageNotWritableException : Could not write JSON: Could not initialize proxy AFTER adding data into DB

node.js - 备份的 Node 请求队列

networking - 如何在 Fortran 中连接到网络?

java - 兔子MQ : Connection recovery mechanism

java - Swing 物质外观下载

java - Google App Engine 仅更新具有许多有效 java 的实体的一个属性

c++ - setsockopt 返回 -1 : errno is set to 0

java - 在 Windows 中绘制缓冲图像速度慢,在 Linux 中速度快

python - UDP 和 TCP 始终为一个客户端使用相同的 IP?

linux - 为什么增加网络缓冲区大小不能减少丢包?