Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a single instance Java application?

Sometime I see many application such as msn, windows media player etc that are single instance applications (when user executes while application is running a new application instance will not created).

In C#, I use Mutex class for this but I don't know how to do this in Java.

like image 340
Fuangwith S. Avatar asked Oct 07 '08 03:10

Fuangwith S.


People also ask

What is a single instance application?

A Single Instance application is an application that limits the program to run only one instance at a time. This means that you cannot open the same program twice.

How do I have one instance of a class?

In object-oriented programming, a singleton class is a class that can have only one object (an instance of the class) at a time. After the first time, if we try to instantiate the Singleton class, the new variable also points to the first instance created.


2 Answers

I use the following method in the main method. This is the simplest, most robust, and least intrusive method I have seen so I thought that I'd share it.

private static boolean lockInstance(final String lockFile) {     try {         final File file = new File(lockFile);         final RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");         final FileLock fileLock = randomAccessFile.getChannel().tryLock();         if (fileLock != null) {             Runtime.getRuntime().addShutdownHook(new Thread() {                 public void run() {                     try {                         fileLock.release();                         randomAccessFile.close();                         file.delete();                     } catch (Exception e) {                         log.error("Unable to remove lock file: " + lockFile, e);                     }                 }             });             return true;         }     } catch (Exception e) {         log.error("Unable to create and/or lock file: " + lockFile, e);     }     return false; } 
like image 162
Robert Avatar answered Sep 28 '22 10:09

Robert


If I believe this article, by :

having the first instance attempt to open a listening socket on the localhost interface. If it's able to open the socket, it is assumed that this is the first instance of the application to be launched. If not, the assumption is that an instance of this application is already running. The new instance must notify the existing instance that a launch was attempted, then exit. The existing instance takes over after receiving the notification and fires an event to the listener that handles the action.

Note: Ahe mentions in the comment that using InetAddress.getLocalHost() can be tricky:

  • it does not work as expected in DHCP-environment because address returned depends on whether the computer has network access.
    Solution was to open connection with InetAddress.getByAddress(new byte[] {127, 0, 0, 1});
    Probably related to bug 4435662.
  • I also found bug 4665037 which reports than Expected results of getLocalHost: return IP address of machine, vs. Actual results : return 127.0.0.1.

it is surprising to have getLocalHost return 127.0.0.1 on Linux but not on windows.


Or you may use ManagementFactory object. As explained here:

The getMonitoredVMs(int processPid) method receives as parameter the current application PID, and catch the application name that is called from command line, for example, the application was started from c:\java\app\test.jar path, then the value variable is "c:\\java\\app\\test.jar". This way, we will catch just application name on the line 17 of the code below.
After that, we search JVM for another process with the same name, if we found it and the application PID is different, it means that is the second application instance.

JNLP offers also a SingleInstanceListener

like image 33
VonC Avatar answered Sep 28 '22 10:09

VonC