How to allow only one instance of a Java program to run at a time?

I need to prevent users from running a Java application (WebStart Swing application) several times. Therefore, if the application is already running, it should not be possible to start it again or again show a warning / be closed.

Is there any convenient way to achieve this? I was thinking of blocking a port or writing sth to a file. But hopefully you can access some properties of the system or JVM?

by the way. target platform - Windows XP with Java 1.5

+26
java java-web-start jnlp
May 28 '09 at 11:28
source share
9 answers

I think your suggestion to open the listening port when the application starts is the best idea.

This is very easy to do, and you don’t need to worry about cleaning it when you close the application. For example, if you write a file, but someone then kills the processes using the task manager, the file will not be deleted.

Also, if I remember correctly, there is no easy way to get the PID of a Java process from the JVM, so don't try to formulate a solution using PID.

Something like this should do the trick:

private static final int PORT = 9999; private static ServerSocket socket; private static void checkIfRunning() { try { //Bind to localhost adapter with a zero connection queue socket = new ServerSocket(PORT,0,InetAddress.getByAddress(new byte[] {127,0,0,1})); } catch (BindException e) { System.err.println("Already running."); System.exit(1); } catch (IOException e) { System.err.println("Unexpected error."); e.printStackTrace(); System.exit(2); } } 

This code example is explicitly bound to 127.0.0.1 , which should avoid any firewall warnings, since any traffic to this address must be from the local system.

When choosing a port, try to avoid mentioning a list of known ports in the list. Ideally, you should use a port that can be configured in a file or through a command line switch in case of conflict.

+34
May 28 '09 at 11:32 a.m.
source share

Since the question says that WebStart is being used, the obvious solution is to use javax.jnlp.SingleInstanceService .

This service is available in version 1.5. Please note that at present 1.5 for the entire service life ends. Get with Java SE 6!

+25
May 28, '09 at 12:33
source share

I think the best idea would be to use file locking (a pretty old idea :)). Starting with Java 1.4, a new I / O library has been introduced that allows you to lock files.

After starting the application, it tries to obtain a file lock (or create it if it does not exist) when the application exits the lock. If the application cannot get the lock, it shuts down.

For example, how to lock files, for example, in Java Developers Almanac .

If you want to use file locking in a Java Web Start application or applet, you need to sing the application or applet.

+3
May 28 '09 at 12:35
source share

We do the same in C ++ by creating a kernel mutex object and looking for it at startup. The benefits are the same as when using a socket, i.e. When a process freezes / crashes / exits /, the mutex object is cleared by the kernel.

I'm not a Java programmer, so I'm not sure if you can do the same in Java?

+1
May 28 '09 at 12:06 a.m.
source share

I created the cross-platform AppLock class.

http://rumatoest.blogspot.com/2015/01/howto-run-only-single-java-application.html

The technology of file locking is used.

Update In 2016-10-14, I created a package compatible with maven / gradle https://github.com/javaplugs/javaplugs and explained it here http://rumatoest.blogspot.com/2015/06/synchronize-code-over- multiple-jvm.html

+1
Jul 20 '12 at 11:08
source share

You can use the JUnique library. It provides support for running a single instance Java application and is open source.

http://www.sauronsoftware.it/projects/junique/

See also my full answer to How to implement a single Java Java application?

+1
Nov 23 '16 at 11:32
source share

You can use the registry, although it carelessly loses the purpose of using a high-level language such as java. At least your target platform: windows = D

0
May 28 '09 at 11:31
source share

Try JUnique:

 String appId = "com.example.win.run.main"; boolean alreadyRunning; try { JUnique.acquireLock(appId); alreadyRunning = false; } catch (AlreadyLockedException e) { alreadyRunning = true; } if (alreadyRunning) { Sysout("An Instance of this app is already running"); System.exit(1); } 
0
Sep 12 '17 at 14:21
source share

I saw so many of these questions, and I was looking for a solution to the same problem regardless of the platform, which does not allow to collide with firewalls or get into the socket.

So here is what I did:

 import java.io.File; import java.io.IOException; /** * This static class is in charge of file-locking the program * so no more than one instance can be run at the same time. * @author nirei */ public class SingleInstanceLock { private static final String LOCK_FILEPATH = System.getProperty("java.io.tmpdir") + File.separator + "lector.lock"; private static final File lock = new File(LOCK_FILEPATH); private static boolean locked = false; private SingleInstanceLock() {} /** * Creates the lock file if it not present and requests its deletion on * program termination or informs that the program is already running if * that the case. * @return true - if the operation was succesful or if the program already has the lock.<br> * false - if the program is already running * @throws IOException if the lock file cannot be created. */ public static boolean lock() throws IOException { if(locked) return true; if(lock.exists()) return false; lock.createNewFile(); lock.deleteOnExit(); locked = true; return true; } } 

Using System.getProperty ("java.io.tmpdir") for the lockfile path ensures that you will always create your lock in one place.

Then from your program, you simply call something like:

 blah blah main(blah blah blah) { try() { if(!SingleInstanceLock.lock()) { System.out.println("The program is already running"); System.exit(0); } } catch (IOException e) { System.err.println("Couldn't create lock file or w/e"); System.exit(1); } } 

And that does it for me. Now, if you kill the program, it will not delete the lock file, but you can solve this problem by writing the PID code of the program in the lock file and making the lock () method if this process is already running. This is left as an assumption for everyone who is interested. :)

-one
Mar 06 '14 at 12:56
source share



All Articles