Daniel, Jim,
In JDK8 the FileHandler file locking was changed to use FileChannel.open with
CREATE_NEW. If the file exists (locked or not) the FileHandler will rotate due
to safety concerns about writing to the same log file. The FileHandler has an
upper bound of 100 as the number of file locks that can be attempted to be
acquired. Given the right pattern, enough time, and enough failures it seems at
it is possible for a program to end up in a state where the FileHandler is
surrounded by zombie lock files refuses log or perform a clean up action.
(A.K.A Farmer Rick Grimes). This means that the lck files have to manually be
deleted or the FileHandler will just fail with an IOException every time it is
created.
A simple test to emulate crashing is to run (JDK7 vs. JDK8) the following code
twice without deleting the log and lck files:
public static void main(String[] args) throws Exception {
System.out.println(System.getProperty("java.runtime.version"));
ReferenceQueue<FileHandler> q = new ReferenceQueue<>();
for (int i=0; i<100; i++) {
WeakReference<FileHandler> h = new WeakReference<>(
new FileHandler("./test_%u.log", 10000, 2, true), q);
while (q.poll() != h) {
System.runFinalization();
System.gc();
System.runFinalization();
Thread.yield();
}
}
}
I understand that if you can't trust that the file locking always works then
there isn't much that can be done. Leaving the number of locks as unbounded
isn't really an option either. Seems like there should be a way to identify
zombie lock files (ATOMIC_MOVE) and delete them. Any thoughts on this?
The source discussion on this can be found at
http://stackoverflow.com/questions/24321098/is-java-util-logging-filehandler-in-java-8-broken
Regards,
Jason