0

我在我的项目中使用 com.sun.net.httpserver.HttpServer。但是,似乎服务器在从 HTTP 连接获取无效数据时会泄漏连接。错误是这个:

http://bugs.sun.com/view_bug.do;jsessionid=dfe841c3152d878571573bafceb8?bug_id=6946825

现在,据报道这已在版本“7(b94)”中得到修复 - 但是,我们仍在使用 Java 1.6,此时我们不太可能想要切换 Java 版本。

所以,我正在寻找解决这种情况的方法。我没有太多时间,所以我更喜欢现在工作的快速解决方案,而不是稍后重新实现很多东西。

我对如何解决这个问题有一些想法:

  • 更新到更新的 Java - 这是我不想做的事情。
  • 找到一个仅包含更新版本的 com.sun.net.httpserver 的 jar,并确保该 jar 在系统 jar 之前加载。
  • 找到 com.sun.net.httpserver 的替代品 - 我愿意在这里提供指点。
  • 修改代码以与另一台嵌入式 HTTP 服务器一起使用,希望与当前的服务器没有太大不同。我可以在一定程度上重写服务器设置代码,但大多数接口应该保持不变。
  • 反编译 com.sun.net.httpserver.ServerImpl 类,修复有问题的地方,然后将该单个类重新编译为它自己的 jar

但是,我愿意接受好的建议!

先感谢您。


修复现已实施并有效。如果其他人需要这些,我将在此处粘贴相关位:

final Field httpserverimpl_server = Class.forName("sun.net.httpserver.HttpServerImpl").getDeclaredField("server");
final Field httpsserverimpl_server = Class.forName("sun.net.httpserver.HttpsServerImpl").getDeclaredField("server");
final Field serverimpl_allconnections = Class.forName("sun.net.httpserver.ServerImpl").getDeclaredField("allConnections");
final Field httpconnection_closed = Class.forName("sun.net.httpserver.HttpConnection").getDeclaredField("closed");

httpserverimpl_server.setAccessible(true);
httpsserverimpl_server.setAccessible(true);
serverimpl_allconnections.setAccessible(true);
httpconnection_closed.setAccessible(true);

Object serverimpl = httpserverimpl_server.get(server);
Set allconnections = (Set)serverimpl_allconnections.get(serverimpl);
LinkedList<Object> toRemove = new LinkedList<Object>();
for (Object conn : allconnections) {
    if (httpconnection_closed.getBoolean(conn)) {
        toRemove.add(conn);
    }
}
for (Object conn : toRemove) {
    allconnections.remove(conn);
}
4

3 回答 3

3

您能否在 HTTP 服务器前面放置一个反向代理,以确保您只允许已知的良好请求通过?清漆或鱿鱼或阿帕奇?

或者在Jetty中敲一些东西,让它充当反向代理?

另一种方法是获取固定版本的源代码,重命名类和包以使其适合您的项目,将类公开,然后改用该实现。

于 2010-08-19T08:32:29.417 回答
2

我可以理解您不愿意升级到 Java 7 的预发布版本。

以下是我的建议:

  • 从 Oracle 获得 Java 支持合同,并让他们为您提供修复错误的 Java 6 补丁。

  • 下载您当前使用的版本的 Java 6 源代码,从 Java 7 源代码中反向移植错误修复并构建。也许您只需要构建某些 JAR 文件。

  • 查看代码,看看您是否可以开发一种解决方法。例如,您可以使用反射来挖掘错误报告中提到的“HttpConnection 实例列表”,并定期删除看起来已经死掉的条目。(我会将此视为最后的手段。)


(更新:2012-05-15)

而且,现在 Java 7 已经很好地发布了(我们现在是 1.7u4):

  • 升级到 Java 7,以及

  • 摆脱您用作临时解决方法的讨厌的反射黑客。

于 2010-08-19T09:27:31.920 回答
0

您可以访问 7(b94) 吗?然后您可以比较源代码并查看是否可以通过覆盖或提供不同的访问器来修复它。

于 2010-08-19T08:19:52.730 回答