Reputation: 11621
I've written a small method that is meant to tell me if another instance of the application is already running. I am aware that there are many ways to find out if another instance is running, but I chose this one. I am creating an empty file and keeping it locked for the duration of the application instance. If another instance is running, the tryLock() method is supposed to return null:
private static boolean alreadyRunning() throws IOException {
FileChannel fc = FileChannel.open(MYLOCKFILE,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.DELETE_ON_CLOSE);
return fc.tryLock() == null;
}
(MYLOCKFILE is a Path
for a file in my temp directory.)
When testing this on Windows 7 Professional 64-bit, I found that it works as expected for the first instance and the second attempted instance. However, after the second instance exits (leaving just the first instance running), when a third instance is run, the tryLock() call throws java.nio.file.AccessDeniedException
instead of returning null. Can you explain this behaviour? If this is considered normal behaviour, how can I differentiate between an existing instance having the file locked, and a real 'access denied' situation such as an idiot setting the TEMP directory to read-only?
Upvotes: 2
Views: 1483
Reputation: 6276
I made a test project and tested the code the only problem because of which java.nio.file.AccessDeniedException
is thrown is StandardOpenOption.DELETE_ON_CLOSE
option used in the code.
I removed the option and it works fine now
FileChannel fc = FileChannel.open(MYLOCKFILE, StandardOpenOption.CREATE,
StandardOpenOption.WRITE);
Explanation that I can think because of which java.nio.file.AccessDeniedException
is thrown is that as soon as your second instance terminates the option StandardOpenOption.DELETE_ON_CLOSE
[More explaination] will attempt to delete the file on JVM exit and failing might have registered an event in kernel or OS to delete the file as and when possible. So if any other process tries to access, create or write the same file before deletion it throws java.nio.file.AccessDeniedException
as a delete operation is already pending for that file.
EDIT
As per your new comment, you can add the following code in try finally
block placed after checking alreadyRunning()
code.
Snippet Example:
if(!alreadyRunning())
{
try
{
// YOUR CODE THAT RUNS
while(true)
{
//YOUR
Thread.sleep(35000);
}
}
finally
{
new File("f:\\test.lock").deleteOnExit();
}
}
Upvotes: 2