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                                     

Reply via email to