views:

43

answers:

3

I'm currently using a temp folder for my Java application to create a lock so that only one instance can be running at a time. This lock file MUST be deleted when the program exits.

This is fine, except for the case when the process is killed (not allowed to shutdown normally, e.g. from Windows Task Manager). If that happens, the user will never be able to run the program again... eek

Anyone have a suggestion? Is there a way to make the OS delete a folder on reboot or something similar? Should I find another way to have a "single instance lock?"

Also, the solution should be cross-platform if possible...

+1  A: 

When the app starts, check for the lock file, and if it exists print an error saying something along the lines: "Either there is another instance running, or you have a stale lock. If there is no other instance running, delete xyz.lock and restart".

A better solution might be to bind to a fixed (and non-standard) TCP port. If you cannot bind to it, assume that there is another instance of your process running.

Third, and probably the best way is to use java.nio.channels.FileLock to take an exclusive lock on a file.

tholomew
I thought about connecting to a Socket, but I don't know much about network programming so it scared me =D. Could you give me some details on what class/method to use for binding to a port?
Tony R
@Tony R The socket approach has issues, If the program terminates the OS will keep the socket for up to 10 minutes or more afterwards, meaning you cannot reuse that port. There are workarounds for that if needed though, but they just reduce the time.
Romain Hippeau
Google for java ServerSocket.
tholomew
@Romain What if the user reboots?
Tony R
@Romain Socket.setSoLinger(false,0) should prevent that, right?
tholomew
In Windows it is a registry setting - You can go down to 30 seconds. http://msdn.microsoft.com/en-us/library/ms819739.aspx
Romain Hippeau
@Tony R if the user reboots the process would not be running on the machine and it should work just fine.
Romain Hippeau
@tholomew - Sorry I updated your post instead of mine - put it back to where it was +1 for trouble
Romain Hippeau
+3  A: 

I think the lock file mentioned is a good way to go: - on application startup, check for the lock file - if it doesn't exist, create it and store the id of the process that creates the file inside that file - if it does exist, read the pid in the file and see if that process is still running - if not, replace the lock file and store your own process id inside - if the process is still running, return an error and quit

Use this(javasysmon) to get the PID as well as the running processes on the box

You should add a ShutDownHook in your main to cleanup the folder, that will catch a large percentage of the terminations.

For more reliable hooking of the JVM look at this paper:
http://www.ibm.com/developerworks/java/library/i-signalhandling/

Romain Hippeau
Most complete answer. Also, Javasysmon is a great little tool. Thanks!
Tony R
A: 

You could look into File.deleteOnExit(). It makes the JVM delete the file when it exits. It can't be undone.

But like the other answers, you'll need to check if it exists when you start up.

jex
This is what I'm currently doing, but the documentation on that method is clear that it only works for normal shutdown of the JVM. I want to be able to toss the computer into a boiling vat of lava and still have the lock released.
Tony R