Saturday, June 23, 2012

Does Java FileLock work in Linux?

Before I write anything I want to mention that the OS is RHEL 4 and the java version is 1.4. Also, the application does not run under any application server - it is standalone console application with main method and there is no multithreading within the code.

The code uses FileLock's The zero-argument tryLock() . The logic is - the first instance of the application acquires lock on a file that either exists or tries to create if it does not and holds until execution finishes and releases it with release(). Other instances try to get the lock and if

Here's the code:

import java.nio.channels.*;

...
public static synchronized boolean isLockObtainedFromFile() throws IOException {
//try to get the lock
try {
while ((MailingThread.LCK = MailingThread.getLockFromFile()) == null) {
Logging.myLogger.info("A previous instance is already running....");
Thread.currentThread().sleep(300000l);
}
Logging.myLogger.info("This is the first instance of this program...");
return true;
} catch (Exception ex) {
Logging.myLogger.error("Locking file not found");
if (MailingThread.LCK != null) {
MailingThread.LCK.release();
}
return false;
}
}



...
public static synchronized FileLock getLockFromFile() {
try {
new DBConstants();
System.out.println(DBConstants.LOCKING_FILE + " this is the locking file");
File file = new File(DBConstants.LOCKING_FILE);
if (!file.exists()) {
file.createNewFile();
}
return new FileOutputStream(DBConstants.LOCKING_FILE).getChannel().
tryLock();
} catch (Exception ex) {
System.out.println("Lock File not found");
System.exit(0);

return null;
}
}
...


So far this looks good. On Windows, this works perfectly, and presumably it did on our Linux machine until we noticed what was in the log file..
2012-06-21 12:07:28,769;main;LOCK RELEASED.
2012-06-21 12:07:28,769;main;******The e-campaign engine executed in total time of - 1344 seconds with total size of - 1015 emails*****
2012-06-21 12:10:05,616;main;This is the first instance of this program...
2012-06-21 12:10:06,686;main;A previous instance is already running....
2012-06-21 12:10:06,914;main;A previous instance is already running....

While the above looks fine - An instance released lock and then an instance that was waiting executes while others that were waiting continues to wait, look below:
2012-06-21 11:55:03,552;main;Send the content to
2012-06-21 11:55:03,552;main;Email has been sent to:
2012-06-21 11:55:04,337;main;This is the first instance of this program...
2012-06-21 11:55:04,750;main;A previous instance is already running....
2012-06-21 11:55:04,773;main;A previous instance is already running....

....

2012-06-21 12:00:04,837;main;Send the content to
2012-06-21 12:00:04,837;main;Email has been sent to:
2012-06-21 12:00:04,837;main;The reply email in send email
2012-06-21 12:00:04,902;main;This is the first instance of this program...
2012-06-21 12:00:04,970;main;Send the content to

Notice the new instances start running when the running instance has not even finished and released the lock. This is a very random behavior and one that is clearly not desired!

Clearly, the lock file is not being used for anything but locking. We're not modifying the content within.

My verdit: Java FileLock does not work in Linux!

 
 

No comments:

Post a Comment