0

Axis と Apache Tomcat 7 を使用して Web サービスを作成しています。このサービスは、サード パーティのライブラリを使用してファイルへの変換を行い、最終的により多くのファイル (サブフォルダーと通常のファイル) を含むフォルダーを作成します。変換が完了すると、サービスは zip アーカイブを作成して返します。新しいリクエストを受け取ると、まず、最後のリクエストで作成されたファイルを削除し、リクエストの処理を開始します。

サービス自体は正常に動作し、少なくとも最初の要求は満たされます。問題は、2 番目の要求を受信したときに、最後の要求で生成されたすべてのファイルをサービスが削除できないことです。私は Windows XP を使用しており、Process Explorer を使用すると、Tomcat がいくつかのファイル (すべてではありません) を開いたままにしていることがわかります。そのため、それを削除できません。

私が使用しているライブラリは、サービス操作が終了してもファイルを開いたままにする可能性はありますか? zip アーカイブの作成に使用するコードでは、開いているすべてのストリームを閉じているようです。ところで、それらを閉じることを許しても、サービス操作がクライアントに結果を返した後も開いたままにすることはできますか? もしそうなら、Tomcat プロセスが一部のファイルしか開いていないのはなぜですか?

しばらくすると一部のファイルが「解放」されたようですが、他のファイルは常に開いたままになっています...

誰かがこの状況に対処する方法についてアドバイスをくれることを願っています:)

4

2 に答える 2

1

役に立つと思われる私のコメントの再投稿。

ファイルハンドラが解放されない場合、サーブレットコンテナがシャットダウンされるまで解放されません。一部の実装では、ファイルハンドラーの解放を、オブジェクトがガベージコレクションされるまで遅らせることもできます。すべてのハンドラーを確実に閉じる以外にできることはありません。サードパーティのライブラリの場合は、バグを報告するか、自分で修正する必要があります。

この種の問題を防ぐための私のベストプラクティスは、ファイルハンドラーが開いているのと同じ方法で閉じられていることを確認することです。その方法で開かない場合は、絶対に閉じないでください。

public void method() {
    //open file handler
    //do something
    //close file handler. make sure it is closed even if there is an exception.
}

また、ファイルハンドラをフィールドにしないでください。

public class A {
    private FileInputStream fin = null; // never do this. you will have hard time keeping track of when to release it.
}
于 2012-05-28T15:28:31.403 に答える
0

さて、私が疑問に思っていたように、私が使用しているライブラリはすべてのファイル ストリームを閉じるわけではありません..

同様の状況で使用できる回避策を見つけました。私はそれを投稿します、多分誰かがそれが役に立つと思うか、問題を解決するためのより良い方法を私にアドバイスしてくれるでしょう:)

幸運なことに、jar ライブラリは java コマンドを使用してコマンド ラインから実行できるので、次のようにランタイムの exec メソッドを使用して実行しました。

try {   
    Process p = Runtime.getRuntime().exec("java -jar library.jar parameters");
p.waitFor();
} catch (InterruptedException | IOException e) {
    e.printStackTrace();
}

このようにして、JVM によって新しいプロセスが作成され、プロセスが終了すると、保留中のすべてのハンドラーが解放されます。

java コマンドでライブラリを実行できない場合、そのようなライブラリは、それを使用して必要なパラメーターを取る単純なクラスによって作成されたカスタム jar に単純にラップできます。その後、ラッパー jar を exec() で実行できます。

于 2012-05-29T09:16:37.230 に答える