まず、簡単なテスト コード:
package javaapplication23;
import java.io.IOException;
import java.util.logging.FileHandler;
public class JavaApplication23 {
public static void main(String[] args) throws IOException {
new FileHandler("./test_%u_%g.log", 10000, 100, true);
}
}
このテストコードは、プログラムを実行する頻度に関係なく、Java 7 で「test_0_0.log」ファイルを 1 つだけ作成します。コンストラクターの追加パラメーターが true に設定されているため、これは予想される動作です。
しかし、このサンプルを Java 8 で実行すると、実行ごとに新しいファイル (test_0_0.log、test_0_1.log、test_0_2.log、...) が作成されます。これはバグだと思います。
私見、Javaの関連する変更はこれです:
@@ -413,18 +428,18 @@
// object. Try again.
continue;
}
- FileChannel fc;
+
try {
- lockStream = new FileOutputStream(lockFileName);
- fc = lockStream.getChannel();
- } catch (IOException ix) {
- // We got an IOException while trying to open the file.
- // Try the next file.
+ lockFileChannel = FileChannel.open(Paths.get(lockFileName),
+ CREATE_NEW, WRITE);
+ } catch (FileAlreadyExistsException ix) {
+ // try the next lock file name in the sequence
continue;
}
+
boolean available;
try {
- available = fc.tryLock() != null;
+ available = lockFileChannel.tryLock() != null;
// We got the lock OK.
} catch (IOException ix) {
// We got an IOException while trying to get the lock.
@@ -440,7 +455,7 @@
}
// We failed to get the lock. Try next file.
- fc.close();
+ lockFileChannel.close();
}
}
(全文: OpenJDK 変更セット 6123:ac22a52a732c )
通常、FileHandler は Logmanager によって閉じられることはわかっていますが、システムまたはアプリケーションがクラッシュしたり、プロセスが強制終了されたりした場合は、そうではありません。これが、上記のサンプル コードに "close" ステートメントがない理由です。
今、私は2つの質問があります:
1) あなたの意見は? これはバグですか?(以下のコメントと回答でほぼ答えられています)
2) Java 8 で古い Java 7 の動作を取得するための回避策を知っていますか? (もっと重要な質問...)
回答ありがとうございます。