2

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...

Tony R
  • 11,224
  • 23
  • 76
  • 101
  • 1
    Does this answer your question? [How to implement a single instance Java application?](https://stackoverflow.com/questions/177189/how-to-implement-a-single-instance-java-application) – Alexander Biryukov Nov 07 '20 at 00:24

3 Answers3

4

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
  • 24,113
  • 5
  • 60
  • 79
1

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.

Romain Hippeau
  • 24,113
  • 5
  • 60
  • 79
carlsborg
  • 2,628
  • 19
  • 21
  • 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 Aug 10 '10 at 01:04
  • @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 Aug 10 '10 at 01:06
  • Google for java ServerSocket. – carlsborg Aug 10 '10 at 01:10
  • @Romain What if the user reboots? – Tony R Aug 10 '10 at 01:15
  • @Romain Socket.setSoLinger(false,0) should prevent that, right? – carlsborg Aug 10 '10 at 01:16
  • 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 Aug 10 '10 at 01:19
  • @Tony R if the user reboots the process would not be running on the machine and it should work just fine. – Romain Hippeau Aug 10 '10 at 01:22
  • @tholomew - Sorry I updated your post instead of mine - put it back to where it was +1 for trouble – Romain Hippeau Aug 10 '10 at 02:02
0

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.

VolatileDream
  • 1,083
  • 7
  • 15
  • 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 Aug 11 '10 at 03:46