Sun Java HTTPServer有一个bug,如何解决?

时间:2010-08-19 08:16:39

标签: java com.sun.net.httpserver

我在我的项目中使用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);
}

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

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

以下是我的建议:

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

  • 下载您当前使用的发行版的Java 6源代码,从Java 7源代码构建错误修复程序。也许你只需要构建某些JAR文件。

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


(更新:2012-05-15)

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

  • 升级到Java 7,

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

答案 2 :(得分:0)

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