Javaについて質問させて頂きます。
XMLパーサにて例外が発生後した後、読み込んだファイルを削除したいのですが、ファイルがロックされてしまっており、削除に失敗してしまう事象が発生しています。
環境:JDK1.6.0_29
OS:WindowsXP
// パーステストクラス
public class ParseTest {
File mFile = null;
// コンストラクタ
public ParseTest(File pFile) {
mFile = pFile;
}
// パース処理
public void parse() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null ;
Document document = null ;
try {
builder = factory.newDocumentBuilder();
try {
document = builder.parse( mFile );
} catch (ParserConfigurationException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (SAXException e) {
throw e;
}
}
}
上記のパーステストクラスにて、parseメソッドの引数に指定するXMLは、わざと例外が発生するようにしています。
(encodingを"UTF-8"と定義し、ファイルの文字コードはShift-JISとする)
以下のテストクラスではパーステストクラスを呼出しており、catchの中にてparseに失敗したファイルをFile#deleteにて削除しようとしていますが、削除に失敗します。デバッグモードにてcatchの途中で止めた状態でWindows上での削除も同様に失敗します。
mainメソッド終了後はWindowsでの削除は成功します。
// テストクラス
public class Test {
public static void main(String[] args) {
File file = new File("/tmp/hoge.xml)";
try {
ParseTest test = new ParseTest(file);
test.parse();
// 例外発生
} catch (Exception e) {
e.printStackTrace() ;
boolean result = file.delete();
// 削除結果がfalseとなってしまう
System.out.println("削除結果=" + result);
}
}
}
検証として、テストクラスのcatchの中にてループさせてみました。
// 例外発生
} catch (Exception e) {
int cnt = 0;
boolean flg = false;
while (!flg) {
boolean rst = file.delete();
System.out.println(cnt++);
if (rst) {
flg = true;
}
}
実行した結果、6000回ほどループしたところで
delete実行結果がtrueとなりました。
推測すると、XMLパーサ関連クラスがすぐにファイルロックを開放しない為、
GCにて開放されるまでロックし続けてしまうのではないかと考えました。
上記のwhile文は使わずに正しいロック開放出きればよいのですが、
該当するようなメソッドが見つけられませんでした。
同じ様な事象を経験して解決されたお方、もしくは解決の糸口となるような
情報をお持ちの方がいらっしゃいましたらご教授頂けますでしょうか。
宜しくお願い致します。