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で何かをノックアップしますか?

もう 1 つの方法は、修正されたバージョンのソース コードを取得し、プロジェクトに適合するようにクラスとパッケージの名前を変更し、クラスを公開してから、代わりにその実装を使用することです。

于 2010-08-19T08:32:29.417 に答える
2

Java7のプレリリースビルドにアップグレードすることに抵抗があることは理解できます。

これが私の提案です:

  • OracleからJavaサポート契約を取得し、バグを修正するJava6のパッチを提供してもらいます。

  • 現在使用しているリリースのJava6ソースをダウンロードし、Java7ソースからバグ修正をバックポートしてビルドします。たぶん、特定の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 に答える