How to let run only one instance of application at a time?

Viewed 540

I am working on a GUI application that uses JavaFX(not fxml) and exported as a JAR. For slow machine, impatient user click more than once on JAR, and multiple instances of application started.

I'm looking for a solution to let only one instance can be run at a time on a system and if the user clicks again while the application is running nothing happens. I think it's called singleton but don't know how to implement it.

4 Answers

You could try JUnique. It's an open source library doing exactly what you ask for. Import junique-1.0.4.jar to your project as a library. It's just 10kb file.

It's manual neatly describes how to implement it on a project. For a JavaFX application, implementation would look something like this:

Make sure to import these classes to your main

import it.sauronsoftware.junique.AlreadyLockedException;
import it.sauronsoftware.junique.JUnique;
    public static void main(String[] args) {

        String appId = "myapplicationid";
        boolean alreadyRunning;
        try {
            JUnique.acquireLock(appId);
            alreadyRunning = false;
        } catch (AlreadyLockedException e) {
            alreadyRunning = true;
        }
        if (!alreadyRunning) {
            launch(args); // <-- This the your default JavaFX start sequence 
        }else{ //This else is optional. Just to free up memory if you're calling the program from a terminal.
            System.exit(1);
        }
    }

One easy solution that I've used is, when you start the application, it creates a file (I named it .lock but you can call it whatever you want), unless the file already exists, in which case the application terminates its execution instead of creating the file.

You will need to bind your application with a resource. It can be a file, port etc. You can change the code on startup to check if the file is locked. The below code will give you some idea

FileOutputStream foStream = new FileOutputStream("/tmp/testfile.txt");
FileChannel channel = fileOutputStream.getChannel();
FileLock lock = channel.lock();

If you'd properly package your JavaFX code as a real application instead of just throwing it into a jar, you might get that functionality for free and without all these hacks. If I package my JavaFX code on my Mac with the jpackage tool, the result will be a full featured macOS application. That means that when I double-click its icon somewhere several times, only one instance of the application will be started. This is the default behaviour on Macs and properly packaged JavaFX applications just stick to that rule too. I can't say however what the behaviour on Windows or Linux is because I currently don't have such a box running. Maybe someone who knows can add this as a comment.

Related