3

I have a jar file that displays a JFrame when it is executed. I don't want to allow duplicate execution of my Jar file. Every time before creating the frame, using Java I want check whether the Jar is already executing. If my app. already has an instance on-screen, I want to bring it to front.

How can I do that? Please suggest me a way.

Channa Jayamuni
  • 1,876
  • 1
  • 18
  • 29
Karthikeyan
  • 406
  • 3
  • 14
  • You have only 2 ways to make it happen: Either a file listener or create a bean with a boolean flag set. – Phani Oct 09 '15 at 12:43
  • 1
    The best way to deploy a Java desktop application is using [Java Web Start](http://stackoverflow.com/tags/java-web-start/info). It includes many handy API's including the [`SingleInstanceService`](https://docs.oracle.com/javase/8/docs/jre/api/javaws/jnlp/javax/jnlp/SingleInstanceService.html) which *"..allow applications launched under Java Web Start to register themselves as singletons, and to be passed in new parameter sets when user attempts to launch new instances of them."* – Andrew Thompson Oct 09 '15 at 12:43
  • 1
    *"You have only 2 ways to make it happen:"* Famous last words. See my comment. It might use either of those ways, or something else entirely (such as securing a `ServerSocket`), but as long as it works reliably x-platform, why worry about the implementation details? – Andrew Thompson Oct 09 '15 at 12:45

4 Answers4

8

There is no regular method in java for single instance of an application. However you can use Socket programming technique to achieve your goal.

When the instance is creating it attempts to listen a ServerSocket. If it could open the ServerSocket it means there are no another instance of the application. So, it keeps the ServerSocket live until the program is shutdown. If it could not open the ServerSocket, it means the application already have another instance. So you can exit application silently. Additionally you don't need to reset your settings when shutdown the application.

Try following example

public class SingletonApplication extends JFrame implements Runnable {

    //count of tried instances
    private int triedInstances = 0;
    //the port number using
    private static final int PORT = 5555;

    public static void main(String[] args) {
        SingletonApplication application = new SingletonApplication();
        application.setTitle("My Singleton Application");
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        application.setSize(500, 500);
        application.setVisible(true);
    }

    public SingletonApplication() {
        super();

        //run socket listening inside a thread
        Thread thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        try {
            //create server socket
            ServerSocket serverSocket = new ServerSocket(PORT);

            //listing the socket to check new instances
            while (true) {
                try {
                    //another instance accessed the socket
                    serverSocket.accept();
                    //bring this to front
                    toFront();

                    //change the title (addtional);
                    triedInstances++;
                    setTitle("Tried another instances : " + triedInstances);
                } catch (IOException ex) {
                    //cannot accept socket
                }
            }
        } catch (IOException ex) {
            //fail if there is an instance already exists
            try {
                //connect to the main instance server socket
                new Socket(InetAddress.getLocalHost(), PORT);
            } catch (IOException ex1) {
                //do nothing
            } finally {
                //exit the system leavng the first instance
                System.exit(0);
            }
        }
    }
}

EDIT:

Additionally: It can pass your runtime arguments into the main instance of the application via the client Socket. So, it's possible to make the main instance to perform required task such opening file or playing music by adding some additional code to read the InputStream of accepted Socket when calling accept() method.

Channa Jayamuni
  • 1,876
  • 1
  • 18
  • 29
3

I had the same situation.

What I did is I used to open a file in write mode and delete the file when I close the application.

By doing this I have a known proof that my program is running.

Each time I open the application I check for the existence of that file and if I find my file, it is running then I used to alert him

"An instance is already running".

Even if one tries to delete that file it says that it is open in another application.

Uma Kanth
  • 5,659
  • 2
  • 20
  • 41
  • 2
    if your application unexpectedly closed, then you will not be able to run the application permanently. and you cannot bring the application to the front. – Channa Jayamuni Oct 09 '15 at 13:24
  • you're right.... that's a valid reason we shall not use File approach rather than socket. – gumuruh Apr 23 '22 at 10:51
3

I used a socket too, via RMI.

The application is an RMI host/server, accepts a Remote Method Invokation on a port.

In the main, at startup on tries as RMI client to get an RMI server on that port. Is it there one does a remote call passing the command line args (to open another document for instance). And then quits.

As a server on being called that remote method one brings the application to front using toFront() of the window.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
2

JUnique accomplishes the first part--blocking multiple instances of the same program. Getting the existing instance to come to the front is another task that I'm not sure how to approach.

MattPutnam
  • 2,927
  • 2
  • 17
  • 23