How to implement a single instance Java application?












86















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.










share|improve this question

























  • A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

    – AZ_
    Nov 16 '13 at 7:03


















86















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.










share|improve this question

























  • A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

    – AZ_
    Nov 16 '13 at 7:03
















86












86








86


48






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.










share|improve this question
















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.







java singleinstance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jun 24 '12 at 17:59









Andrew Thompson

154k28164347




154k28164347










asked Oct 7 '08 at 3:54









Fuangwith S.Fuangwith S.

3,49973139




3,49973139













  • A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

    – AZ_
    Nov 16 '13 at 7:03





















  • A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

    – AZ_
    Nov 16 '13 at 7:03



















A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

– AZ_
Nov 16 '13 at 7:03







A very simple approach with java NIO see complete example stackoverflow.com/a/20015771/185022

– AZ_
Nov 16 '13 at 7:03














15 Answers
15






active

oldest

votes


















58














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






share|improve this answer





















  • 3





    Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

    – Ahe
    Sep 17 '10 at 8:31








  • 2





    @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

    – VonC
    Sep 17 '10 at 8:41






  • 2





    According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

    – kayahr
    Feb 9 '12 at 8:55






  • 3





    See also Using the SingleInstanceService Service.

    – trashgod
    Jan 17 '13 at 16:56






  • 1





    @Puce Sure, no problem: I have restored those links.

    – VonC
    Sep 23 '15 at 17:46



















57














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;
}





share|improve this answer



















  • 1





    What operating systems have you verified this to work on?

    – Thorbjørn Ravn Andersen
    Nov 26 '12 at 11:14











  • I can confirm this works on Windows 7/8 platforms.

    – resilva87
    Apr 19 '14 at 23:27






  • 2





    Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

    – Natix
    Oct 7 '14 at 14:50






  • 4





    But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

    – Petr Hudeček
    Dec 13 '14 at 18:28






  • 3





    @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

    – Dreamspace President
    Dec 21 '15 at 12:23



















9














If the app. has a GUI, launch it with JWS and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.






share|improve this answer



















  • 1





    Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

    – Thorbjørn Ravn Andersen
    Nov 26 '12 at 11:17



















7














Yes this is a really decent answer for eclipse RCP eclipse single instance application
below is my code



in application.java



if(!isFileshipAlreadyRunning()){
MessageDialog.openError(display.getActiveShell(), "Fileship already running", "Another instance of this application is already running. Exiting.");
return IApplication.EXIT_OK;
}


private static boolean isFileshipAlreadyRunning() {
// socket concept is shown at http://www.rbgrn.net/content/43-java-single-application-instance
// but this one is really great
try {
final File file = new File("FileshipReserved.txt");
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;
}





share|improve this answer

































    5














    We use file locking for this (grab an exclusive lock on a magic file in the user's app data directory), but we are primarily interested in preventing multiple instances from ever running.



    If you are trying to have the second instance pass command line args, etc... to the first instance, then using a socket connection on localhost will be killing two birds with one stone. General algorithm:




    • On launch, try to open listener on port XXXX on localhost

    • if fail, open a writer to that port on localhost and send the command line args, then shutdown

    • otherwise, listen on port XXXXX on localhost. When receive command line args, process them as if the app was launched with that command line.






    share|improve this answer































      5














      I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:



      http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html



      I think it will be a help to those with a strict firewall setting.






      share|improve this answer
























      • Yes, it's a good way as the lock would be released event if the application crashed or so :)

        – LE GALL Benoît
        Jun 18 '15 at 14:45



















      5














      You can use JUnique library. It provides support for running single-instance java application and is open-source.



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




      The JUnique library can be used to prevent a user to run at the same
      time more instances of the same Java application.



      JUnique implements locks and communication channels shared between all
      the JVM instances launched by the same user.




      public static void main(String args) {
      String appId = "myapplicationid";
      boolean alreadyRunning;
      try {
      JUnique.acquireLock(appId, new MessageHandler() {
      public String handle(String message) {
      // A brand new argument received! Handle it!
      return null;
      }
      });
      alreadyRunning = false;
      } catch (AlreadyLockedException e) {
      alreadyRunning = true;
      }
      if (!alreadyRunning) {
      // Start sequence here
      } else {
      for (int i = 0; i < args.length; i++) {
      JUnique.sendMessage(appId, args[0]));
      }
      }
      }


      Under the hood, it creates file locks in %USER_DATA%/.junique folder and creates a server socket at random port for each unique appId that allows sending/receiving messages between java applications.






      share|improve this answer
























      • Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

        – Wuaner
        Apr 25 '17 at 2:29



















      4














      On Windows, you can use launch4j.






      share|improve this answer































        2














        ManagementFactory class supported in J2SE 5.0 or later detail



        but now i use J2SE 1.4 and I found this one http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ but I never test. What do you think about it?






        share|improve this answer
























        • I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

          – VonC
          Oct 7 '08 at 6:20



















        2














        You could try using the Preferences API. It is platform independent.






        share|improve this answer
























        • I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

          – Cal
          Nov 1 '09 at 4:43











        • @Cal But the same issue is with file changing/locking/etc...don't you think?

          – Alex
          Oct 1 '13 at 11:26



















        2














        A more generic way of limiting the number of instance's on a single machine, or even an entire network, is to use a multicast socket.



        Using a multicast socket, enables you to broadcast a message to any amount of instances of your application, some of which can be on physically remote machines across a corporate network.



        In this way you can enable many types of configurations, to control things like




        • One or Many instances per machine

        • One or Many instances per network (eg controlling installs on a client site)


        Java's multicast support is via java.net package with MulticastSocket & DatagramSocket being the main tools.



        Note: MulticastSocket's do not guarantee delivery of data packets, so you should use a tool built on top of multicast sockets like JGroups. JGroups does guarantee delivery of all data. It is one single jar file, with a very simple API.



        JGroups has been around a while, and has some impressive usages in industry, for example it underpins JBoss's clustering mechanism do broadcast data to all instance of a cluster.



        To use JGroups, to limit the number of instances of an app (on a machine or a network, lets say: to the number of licences a customer has bought) is conceptually very simple :




        • Upon startup of your application, each instance tries to join a named group eg "My Great App Group". You will have configured this group to allow 0, 1 or N members

        • When the group member count is greater than what you have configured for it.. your app should refuse to start up.






        share|improve this answer

































          1














          You can open a Memory Mapped File and then see if that file is OPEN already. if it is already open, you can return from main.



          Other ways is to use lock files(standard unix practice). One more way is to put something into the clipboard when main starts after checking if something is already in the clipboard.



          Else, you can open a socket in a listen mode(ServerSocket). First try to connect to hte socket ; if you cannot connect, then open a serversocket. if you connect, then you know that another instance is already running.



          So, pretty much any system resource can be used for knowing that an app is running.



          BR,
          ~A






          share|improve this answer
























          • do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

            – android developer
            Oct 2 '13 at 12:15



















          1














          I used sockets for that and depending if the application is on the client side or server side the behavior is a bit different:




          • client side : if an instance already exists(I cannot listen on a specific port) I will pass the application parameters and exit(you may want to perform some actions in the previous instance) if not I will start the application.

          • server side : if an instance already exists I will print a message and exit, if not I will start the application.






          share|improve this answer































            1
















            public class SingleInstance {
            public static final String LOCK = System.getProperty("user.home") + File.separator + "test.lock";
            public static final String PIPE = System.getProperty("user.home") + File.separator + "test.pipe";
            private static JFrame frame = null;

            public static void main(String args) {
            try {
            FileChannel lockChannel = new RandomAccessFile(LOCK, "rw").getChannel();
            FileLock flk = null;
            try {
            flk = lockChannel.tryLock();
            } catch(Throwable t) {
            t.printStackTrace();
            }
            if (flk == null || !flk.isValid()) {
            System.out.println("alread running, leaving a message to pipe and quitting...");
            FileChannel pipeChannel = null;
            try {
            pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
            MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
            bb.put(0, (byte)1);
            bb.force();
            } catch (Throwable t) {
            t.printStackTrace();
            } finally {
            if (pipeChannel != null) {
            try {
            pipeChannel.close();
            } catch (Throwable t) {
            t.printStackTrace();
            }
            }
            }
            System.exit(0);
            }
            //We do not release the lock and close the channel here,
            // which will be done after the application crashes or closes normally.
            SwingUtilities.invokeLater(
            new Runnable() {
            public void run() {
            createAndShowGUI();
            }
            }
            );

            FileChannel pipeChannel = null;
            try {
            pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
            MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
            while (true) {
            byte b = bb.get(0);
            if (b > 0) {
            bb.put(0, (byte)0);
            bb.force();
            SwingUtilities.invokeLater(
            new Runnable() {
            public void run() {
            frame.setExtendedState(JFrame.NORMAL);
            frame.setAlwaysOnTop(true);
            frame.toFront();
            frame.setAlwaysOnTop(false);
            }
            }
            );
            }
            Thread.sleep(1000);
            }
            } catch (Throwable t) {
            t.printStackTrace();
            } finally {
            if (pipeChannel != null) {
            try {
            pipeChannel.close();
            } catch (Throwable t) {
            t.printStackTrace();
            }
            }
            }
            } catch(Throwable t) {
            t.printStackTrace();
            }
            }

            public static void createAndShowGUI() {

            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800, 650);
            frame.getContentPane().add(new JLabel("MAIN WINDOW",
            SwingConstants.CENTER), BorderLayout.CENTER);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            }
            }






            share|improve this answer































              0














              EDIT: Instead of using this WatchService approach, a simple 1 second timer thread could be used to check if the indicatorFile.exists(). Delete it, then bring the application toFront().



              EDIT: I would like to know why this was downvoted. It's the best solution I have seen so far. E.g. the server socket approach fails if another application happens to already be listening to the port.



              Just download Microsoft Windows Sysinternals TCPView (or use netstat), start it, sort by "State", look for the line block that says "LISTENING", pick one whose remote address says your computer's name, put that port into your new-Socket()-solution. In my implementation of it, I can produce failure every time. And it's logical, because it's the very foundation of the approach. Or what am I not getting regarding how to implement this?



              Please inform me if and how I am wrong about this!



              My view - which I am asking you to disprove if possible - is that developers are being advised to use an approach in production code that will fail in at least 1 of about 60000 cases. And if this view happens to be correct, then it can absolutely not be that a solution presented that does not have this problem is downvoted and criticized for its amount of code.



              Disadvantages of the socket approach in comparison:




              • Fails if the wrong lottery ticket (port number) is chosen.

              • Fails in multi user environment: Only one user can run the application at the same time. (My approach would have to be slightly changed to create the file(s) in the user tree, but that's trivial.)

              • Fails if firewall rules are too strict.

              • Makes suspicious users (which I did meet in the wild) wonder what shenanigans you're up to when your text editor is claiming a server socket.




              I just had a nice idea for how to solve the new-instance-to-existing-instance Java communication problem in a way that should work on every system. So, I whipped up this class in about two hours. Works like a charm :D



              It's based on Robert's file lock approach (also on this page), which I have used ever since. To tell the already running instance that another instance tried to start (but didn't) ... a file is created and immediately deleted, and the first instance uses the WatchService to detect this folder content change. I can't believe that apparently this is a new idea, given how fundamental the problem is.



              This can easily be changed to just create and not delete the file, and then information can be put into it that the proper instance can evaluate, e.g. the command line arguments - and the proper instance can then perform the deletion. Personally, I only needed to know when to restore my application's window and send it to front.



              Example use:



              public static void main(final String args) {

              // ENSURE SINGLE INSTANCE
              if (!SingleInstanceChecker.INSTANCE.isOnlyInstance(Main::otherInstanceTriedToLaunch, false)) {
              System.exit(0);
              }

              // launch rest of application here
              System.out.println("Application starts properly because it's the only instance.");
              }

              private static void otherInstanceTriedToLaunch() {
              // Restore your application window and bring it to front.
              // But make sure your situation is apt: This method could be called at *any* time.
              System.err.println("Deiconified because other instance tried to start.");
              }


              Here's the class:



              package yourpackagehere;

              import javax.swing.*;
              import java.io.File;
              import java.io.IOException;
              import java.io.RandomAccessFile;
              import java.nio.channels.FileLock;
              import java.nio.file.*;




              /**
              * SingleInstanceChecker v[(2), 2016-04-22 08:00 UTC] by dreamspace-president.com
              * <p>
              * (file lock single instance solution by Robert https://stackoverflow.com/a/2002948/3500521)
              */
              public enum SingleInstanceChecker {

              INSTANCE; // HAHA! The CONFUSION!


              final public static int POLLINTERVAL = 1000;
              final public static File LOCKFILE = new File("SINGLE_INSTANCE_LOCKFILE");
              final public static File DETECTFILE = new File("EXTRA_INSTANCE_DETECTFILE");


              private boolean hasBeenUsedAlready = false;


              private WatchService watchService = null;
              private RandomAccessFile randomAccessFileForLock = null;
              private FileLock fileLock = null;


              /**
              * CAN ONLY BE CALLED ONCE.
              * <p>
              * Assumes that the program will close if FALSE is returned: The other-instance-tries-to-launch listener is not
              * installed in that case.
              * <p>
              * Checks if another instance is already running (temp file lock / shutdownhook). Depending on the accessibility of
              * the temp file the return value will be true or false. This approach even works even if the virtual machine
              * process gets killed. On the next run, the program can even detect if it has shut down irregularly, because then
              * the file will still exist. (Thanks to Robert https://stackoverflow.com/a/2002948/3500521 for that solution!)
              * <p>
              * Additionally, the method checks if another instance tries to start. In a crappy way, because as awesome as Java
              * is, it lacks some fundamental features. Don't worry, it has only been 25 years, it'll sure come eventually.
              *
              * @param codeToRunIfOtherInstanceTriesToStart Can be null. If not null and another instance tries to start (which
              * changes the detect-file), the code will be executed. Could be used to
              * bring the current (=old=only) instance to front. If null, then the
              * watcher will not be installed at all, nor will the trigger file be
              * created. (Null means that you just don't want to make use of this
              * half of the class' purpose, but then you would be better advised to
              * just use the 24 line method by Robert.)
              * <p>
              * BE CAREFUL with the code: It will potentially be called until the
              * very last moment of the program's existence, so if you e.g. have a
              * shutdown procedure or a window that would be brought to front, check
              * if the procedure has not been triggered yet or if the window still
              * exists / hasn't been disposed of yet. Or edit this class to be more
              * comfortable. This would e.g. allow you to remove some crappy
              * comments. Attribution would be nice, though.
              * @param executeOnAWTEventDispatchThread Convenience function. If false, the code will just be executed. If
              * true, it will be detected if we're currently on that thread. If so,
              * the code will just be executed. If not so, the code will be run via
              * SwingUtilities.invokeLater().
              * @return if this is the only instance
              */
              public boolean isOnlyInstance(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

              if (hasBeenUsedAlready) {
              throw new IllegalStateException("This class/method can only be used once, which kinda makes sense if you think about it.");
              }
              hasBeenUsedAlready = true;

              final boolean ret = canLockFileBeCreatedAndLocked();

              if (codeToRunIfOtherInstanceTriesToStart != null) {
              if (ret) {
              // Only if this is the only instance, it makes sense to install a watcher for additional instances.
              installOtherInstanceLaunchAttemptWatcher(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread);
              } else {
              // Only if this is NOT the only instance, it makes sense to create&delete the trigger file that will effect notification of the other instance.
              //
              // Regarding "codeToRunIfOtherInstanceTriesToStart != null":
              // While creation/deletion of the file concerns THE OTHER instance of the program,
              // making it dependent on the call made in THIS instance makes sense
              // because the code executed is probably the same.
              createAndDeleteOtherInstanceWatcherTriggerFile();
              }
              }

              optionallyInstallShutdownHookThatCleansEverythingUp();

              return ret;
              }


              private void createAndDeleteOtherInstanceWatcherTriggerFile() {

              try {
              final RandomAccessFile randomAccessFileForDetection = new RandomAccessFile(DETECTFILE, "rw");
              randomAccessFileForDetection.close();
              Files.deleteIfExists(DETECTFILE.toPath()); // File is created and then instantly deleted. Not a problem for the WatchService :)
              } catch (Exception e) {
              e.printStackTrace();
              }
              }


              private boolean canLockFileBeCreatedAndLocked() {

              try {
              randomAccessFileForLock = new RandomAccessFile(LOCKFILE, "rw");
              fileLock = randomAccessFileForLock.getChannel().tryLock();
              return fileLock != null;
              } catch (Exception e) {
              return false;
              }
              }


              private void installOtherInstanceLaunchAttemptWatcher(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

              // PREPARE WATCHSERVICE AND STUFF
              try {
              watchService = FileSystems.getDefault().newWatchService();
              } catch (IOException e) {
              e.printStackTrace();
              return;
              }
              final File appFolder = new File("").getAbsoluteFile(); // points to current folder
              final Path appFolderWatchable = appFolder.toPath();


              // REGISTER CURRENT FOLDER FOR WATCHING FOR FILE DELETIONS
              try {
              appFolderWatchable.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
              } catch (IOException e) {
              e.printStackTrace();
              return;
              }


              // INSTALL WATCHER THAT LOOKS IF OUR detectFile SHOWS UP IN THE DIRECTORY CHANGES. IF THERE'S A CHANGE, ANOTHER INSTANCE TRIED TO START, SO NOTIFY THE CURRENT ONE OF THAT.
              final Thread t = new Thread(() -> watchForDirectoryChangesOnExtraThread(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread));
              t.setDaemon(true);
              t.setName("directory content change watcher");
              t.start();
              }


              private void optionallyInstallShutdownHookThatCleansEverythingUp() {

              if (fileLock == null && randomAccessFileForLock == null && watchService == null) {
              return;
              }

              final Thread shutdownHookThread = new Thread(() -> {
              try {
              if (fileLock != null) {
              fileLock.release();
              }
              if (randomAccessFileForLock != null) {
              randomAccessFileForLock.close();
              }
              Files.deleteIfExists(LOCKFILE.toPath());
              } catch (Exception ignore) {
              }
              if (watchService != null) {
              try {
              watchService.close();
              } catch (IOException e) {
              e.printStackTrace();
              }
              }
              });
              Runtime.getRuntime().addShutdownHook(shutdownHookThread);
              }


              private void watchForDirectoryChangesOnExtraThread(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

              while (true) { // To eternity and beyond! Until the universe shuts down. (Should be a volatile boolean, but this class only has absolutely required features.)

              try {
              Thread.sleep(POLLINTERVAL);
              } catch (InterruptedException e) {
              e.printStackTrace();
              }


              final WatchKey wk;
              try {
              wk = watchService.poll();
              } catch (ClosedWatchServiceException e) {
              // This situation would be normal if the watcher has been closed, but our application never does that.
              e.printStackTrace();
              return;
              }

              if (wk == null || !wk.isValid()) {
              continue;
              }


              for (WatchEvent<?> we : wk.pollEvents()) {

              final WatchEvent.Kind<?> kind = we.kind();
              if (kind == StandardWatchEventKinds.OVERFLOW) {
              System.err.println("OVERFLOW of directory change events!");
              continue;
              }


              final WatchEvent<Path> watchEvent = (WatchEvent<Path>) we;
              final File file = watchEvent.context().toFile();


              if (file.equals(DETECTFILE)) {

              if (!executeOnAWTEventDispatchThread || SwingUtilities.isEventDispatchThread()) {
              codeToRunIfOtherInstanceTriesToStart.run();
              } else {
              SwingUtilities.invokeLater(codeToRunIfOtherInstanceTriesToStart);
              }

              break;

              } else {
              System.err.println("THIS IS THE FILE THAT WAS DELETED: " + file);
              }

              }

              wk.reset();
              }
              }

              }





              share|improve this answer


























              • You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                – user207421
                Apr 22 '16 at 8:30











              • @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                – Dreamspace President
                Apr 22 '16 at 12:45











              • @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                – Dreamspace President
                Apr 26 '16 at 9:26











              • @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                – Dreamspace President
                Apr 26 '16 at 9:34











              • @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                – Dreamspace President
                May 4 '16 at 12:45












              protected by Community Feb 4 '16 at 16:43



              Thank you for your interest in this question.
              Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



              Would you like to answer one of these unanswered questions instead?














              15 Answers
              15






              active

              oldest

              votes








              15 Answers
              15






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              58














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






              share|improve this answer





















              • 3





                Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

                – Ahe
                Sep 17 '10 at 8:31








              • 2





                @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

                – VonC
                Sep 17 '10 at 8:41






              • 2





                According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

                – kayahr
                Feb 9 '12 at 8:55






              • 3





                See also Using the SingleInstanceService Service.

                – trashgod
                Jan 17 '13 at 16:56






              • 1





                @Puce Sure, no problem: I have restored those links.

                – VonC
                Sep 23 '15 at 17:46
















              58














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






              share|improve this answer





















              • 3





                Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

                – Ahe
                Sep 17 '10 at 8:31








              • 2





                @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

                – VonC
                Sep 17 '10 at 8:41






              • 2





                According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

                – kayahr
                Feb 9 '12 at 8:55






              • 3





                See also Using the SingleInstanceService Service.

                – trashgod
                Jan 17 '13 at 16:56






              • 1





                @Puce Sure, no problem: I have restored those links.

                – VonC
                Sep 23 '15 at 17:46














              58












              58








              58







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






              share|improve this answer















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







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited May 23 '17 at 12:34









              Community

              11




              11










              answered Oct 7 '08 at 4:01









              VonCVonC

              849k29826993258




              849k29826993258








              • 3





                Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

                – Ahe
                Sep 17 '10 at 8:31








              • 2





                @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

                – VonC
                Sep 17 '10 at 8:41






              • 2





                According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

                – kayahr
                Feb 9 '12 at 8:55






              • 3





                See also Using the SingleInstanceService Service.

                – trashgod
                Jan 17 '13 at 16:56






              • 1





                @Puce Sure, no problem: I have restored those links.

                – VonC
                Sep 23 '15 at 17:46














              • 3





                Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

                – Ahe
                Sep 17 '10 at 8:31








              • 2





                @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

                – VonC
                Sep 17 '10 at 8:41






              • 2





                According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

                – kayahr
                Feb 9 '12 at 8:55






              • 3





                See also Using the SingleInstanceService Service.

                – trashgod
                Jan 17 '13 at 16:56






              • 1





                @Puce Sure, no problem: I have restored those links.

                – VonC
                Sep 23 '15 at 17:46








              3




              3





              Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

              – Ahe
              Sep 17 '10 at 8:31







              Be aware that the fist solution has a bug. We recently discovered that InetAddress.getLocalHost() 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});.

              – Ahe
              Sep 17 '10 at 8:31






              2




              2





              @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

              – VonC
              Sep 17 '10 at 8:41





              @Ahe: excellent point. I have included your comment as well as Oracle-Sun bug report references in my edited answer.

              – VonC
              Sep 17 '10 at 8:41




              2




              2





              According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

              – kayahr
              Feb 9 '12 at 8:55





              According to JavaDoc InetAddress.getByName(null) returns the address of the loop back interface. I guess this is better then specifying 127.0.0.1 manually because in theory this should also work in IPv6-only environments.

              – kayahr
              Feb 9 '12 at 8:55




              3




              3





              See also Using the SingleInstanceService Service.

              – trashgod
              Jan 17 '13 at 16:56





              See also Using the SingleInstanceService Service.

              – trashgod
              Jan 17 '13 at 16:56




              1




              1





              @Puce Sure, no problem: I have restored those links.

              – VonC
              Sep 23 '15 at 17:46





              @Puce Sure, no problem: I have restored those links.

              – VonC
              Sep 23 '15 at 17:46













              57














              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;
              }





              share|improve this answer



















              • 1





                What operating systems have you verified this to work on?

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:14











              • I can confirm this works on Windows 7/8 platforms.

                – resilva87
                Apr 19 '14 at 23:27






              • 2





                Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

                – Natix
                Oct 7 '14 at 14:50






              • 4





                But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

                – Petr Hudeček
                Dec 13 '14 at 18:28






              • 3





                @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

                – Dreamspace President
                Dec 21 '15 at 12:23
















              57














              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;
              }





              share|improve this answer



















              • 1





                What operating systems have you verified this to work on?

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:14











              • I can confirm this works on Windows 7/8 platforms.

                – resilva87
                Apr 19 '14 at 23:27






              • 2





                Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

                – Natix
                Oct 7 '14 at 14:50






              • 4





                But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

                – Petr Hudeček
                Dec 13 '14 at 18:28






              • 3





                @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

                – Dreamspace President
                Dec 21 '15 at 12:23














              57












              57








              57







              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;
              }





              share|improve this answer













              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;
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 4 '10 at 23:07









              RobertRobert

              58444




              58444








              • 1





                What operating systems have you verified this to work on?

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:14











              • I can confirm this works on Windows 7/8 platforms.

                – resilva87
                Apr 19 '14 at 23:27






              • 2





                Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

                – Natix
                Oct 7 '14 at 14:50






              • 4





                But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

                – Petr Hudeček
                Dec 13 '14 at 18:28






              • 3





                @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

                – Dreamspace President
                Dec 21 '15 at 12:23














              • 1





                What operating systems have you verified this to work on?

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:14











              • I can confirm this works on Windows 7/8 platforms.

                – resilva87
                Apr 19 '14 at 23:27






              • 2





                Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

                – Natix
                Oct 7 '14 at 14:50






              • 4





                But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

                – Petr Hudeček
                Dec 13 '14 at 18:28






              • 3





                @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

                – Dreamspace President
                Dec 21 '15 at 12:23








              1




              1





              What operating systems have you verified this to work on?

              – Thorbjørn Ravn Andersen
              Nov 26 '12 at 11:14





              What operating systems have you verified this to work on?

              – Thorbjørn Ravn Andersen
              Nov 26 '12 at 11:14













              I can confirm this works on Windows 7/8 platforms.

              – resilva87
              Apr 19 '14 at 23:27





              I can confirm this works on Windows 7/8 platforms.

              – resilva87
              Apr 19 '14 at 23:27




              2




              2





              Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

              – Natix
              Oct 7 '14 at 14:50





              Is it really necessary to manually release the file lock and close the file on shutdown? Doesn't this happen automatically when the process dies?

              – Natix
              Oct 7 '14 at 14:50




              4




              4





              But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

              – Petr Hudeček
              Dec 13 '14 at 18:28





              But what happens if the power dies and the computer shuts down without running the shutdown hook? The file will persist and the application will be unlaunchable.

              – Petr Hudeček
              Dec 13 '14 at 18:28




              3




              3





              @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

              – Dreamspace President
              Dec 21 '15 at 12:23





              @PetrHudeček It's alright. No matter how the application ends, the file lock will be released. If it was not a proper shutdown, then this even has the benefit of allowing the application to realize this on the next run. In any case: The lock is what counts, not the presence of the file itself. If the file is still there, the application will launch anyway.

              – Dreamspace President
              Dec 21 '15 at 12:23











              9














              If the app. has a GUI, launch it with JWS and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.






              share|improve this answer



















              • 1





                Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:17
















              9














              If the app. has a GUI, launch it with JWS and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.






              share|improve this answer



















              • 1





                Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:17














              9












              9








              9







              If the app. has a GUI, launch it with JWS and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.






              share|improve this answer













              If the app. has a GUI, launch it with JWS and use the SingleInstanceService. See the demo. of the SingleInstanceService for (demo. and) example code.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Aug 24 '11 at 14:04









              Andrew ThompsonAndrew Thompson

              154k28164347




              154k28164347








              • 1





                Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:17














              • 1





                Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

                – Thorbjørn Ravn Andersen
                Nov 26 '12 at 11:17








              1




              1





              Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

              – Thorbjørn Ravn Andersen
              Nov 26 '12 at 11:17





              Also note that it appears that the running instance can be informed of new instances and their arguments making it easy to communicate into such a program.

              – Thorbjørn Ravn Andersen
              Nov 26 '12 at 11:17











              7














              Yes this is a really decent answer for eclipse RCP eclipse single instance application
              below is my code



              in application.java



              if(!isFileshipAlreadyRunning()){
              MessageDialog.openError(display.getActiveShell(), "Fileship already running", "Another instance of this application is already running. Exiting.");
              return IApplication.EXIT_OK;
              }


              private static boolean isFileshipAlreadyRunning() {
              // socket concept is shown at http://www.rbgrn.net/content/43-java-single-application-instance
              // but this one is really great
              try {
              final File file = new File("FileshipReserved.txt");
              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;
              }





              share|improve this answer






























                7














                Yes this is a really decent answer for eclipse RCP eclipse single instance application
                below is my code



                in application.java



                if(!isFileshipAlreadyRunning()){
                MessageDialog.openError(display.getActiveShell(), "Fileship already running", "Another instance of this application is already running. Exiting.");
                return IApplication.EXIT_OK;
                }


                private static boolean isFileshipAlreadyRunning() {
                // socket concept is shown at http://www.rbgrn.net/content/43-java-single-application-instance
                // but this one is really great
                try {
                final File file = new File("FileshipReserved.txt");
                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;
                }





                share|improve this answer




























                  7












                  7








                  7







                  Yes this is a really decent answer for eclipse RCP eclipse single instance application
                  below is my code



                  in application.java



                  if(!isFileshipAlreadyRunning()){
                  MessageDialog.openError(display.getActiveShell(), "Fileship already running", "Another instance of this application is already running. Exiting.");
                  return IApplication.EXIT_OK;
                  }


                  private static boolean isFileshipAlreadyRunning() {
                  // socket concept is shown at http://www.rbgrn.net/content/43-java-single-application-instance
                  // but this one is really great
                  try {
                  final File file = new File("FileshipReserved.txt");
                  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;
                  }





                  share|improve this answer















                  Yes this is a really decent answer for eclipse RCP eclipse single instance application
                  below is my code



                  in application.java



                  if(!isFileshipAlreadyRunning()){
                  MessageDialog.openError(display.getActiveShell(), "Fileship already running", "Another instance of this application is already running. Exiting.");
                  return IApplication.EXIT_OK;
                  }


                  private static boolean isFileshipAlreadyRunning() {
                  // socket concept is shown at http://www.rbgrn.net/content/43-java-single-application-instance
                  // but this one is really great
                  try {
                  final File file = new File("FileshipReserved.txt");
                  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;
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Mar 21 '11 at 20:44









                  Josh Kelley

                  42k15107192




                  42k15107192










                  answered Nov 23 '10 at 13:39









                  parvez Ahmadparvez Ahmad

                  7911




                  7911























                      5














                      We use file locking for this (grab an exclusive lock on a magic file in the user's app data directory), but we are primarily interested in preventing multiple instances from ever running.



                      If you are trying to have the second instance pass command line args, etc... to the first instance, then using a socket connection on localhost will be killing two birds with one stone. General algorithm:




                      • On launch, try to open listener on port XXXX on localhost

                      • if fail, open a writer to that port on localhost and send the command line args, then shutdown

                      • otherwise, listen on port XXXXX on localhost. When receive command line args, process them as if the app was launched with that command line.






                      share|improve this answer




























                        5














                        We use file locking for this (grab an exclusive lock on a magic file in the user's app data directory), but we are primarily interested in preventing multiple instances from ever running.



                        If you are trying to have the second instance pass command line args, etc... to the first instance, then using a socket connection on localhost will be killing two birds with one stone. General algorithm:




                        • On launch, try to open listener on port XXXX on localhost

                        • if fail, open a writer to that port on localhost and send the command line args, then shutdown

                        • otherwise, listen on port XXXXX on localhost. When receive command line args, process them as if the app was launched with that command line.






                        share|improve this answer


























                          5












                          5








                          5







                          We use file locking for this (grab an exclusive lock on a magic file in the user's app data directory), but we are primarily interested in preventing multiple instances from ever running.



                          If you are trying to have the second instance pass command line args, etc... to the first instance, then using a socket connection on localhost will be killing two birds with one stone. General algorithm:




                          • On launch, try to open listener on port XXXX on localhost

                          • if fail, open a writer to that port on localhost and send the command line args, then shutdown

                          • otherwise, listen on port XXXXX on localhost. When receive command line args, process them as if the app was launched with that command line.






                          share|improve this answer













                          We use file locking for this (grab an exclusive lock on a magic file in the user's app data directory), but we are primarily interested in preventing multiple instances from ever running.



                          If you are trying to have the second instance pass command line args, etc... to the first instance, then using a socket connection on localhost will be killing two birds with one stone. General algorithm:




                          • On launch, try to open listener on port XXXX on localhost

                          • if fail, open a writer to that port on localhost and send the command line args, then shutdown

                          • otherwise, listen on port XXXXX on localhost. When receive command line args, process them as if the app was launched with that command line.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Oct 7 '08 at 4:26









                          Kevin DayKevin Day

                          13.6k73159




                          13.6k73159























                              5














                              I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:



                              http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html



                              I think it will be a help to those with a strict firewall setting.






                              share|improve this answer
























                              • Yes, it's a good way as the lock would be released event if the application crashed or so :)

                                – LE GALL Benoît
                                Jun 18 '15 at 14:45
















                              5














                              I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:



                              http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html



                              I think it will be a help to those with a strict firewall setting.






                              share|improve this answer
























                              • Yes, it's a good way as the lock would be released event if the application crashed or so :)

                                – LE GALL Benoît
                                Jun 18 '15 at 14:45














                              5












                              5








                              5







                              I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:



                              http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html



                              I think it will be a help to those with a strict firewall setting.






                              share|improve this answer













                              I have found a solution, a bit cartoonish explanation, but still works in most cases. It uses the plain old lock file creating stuff, but in a quite different view:



                              http://javalandscape.blogspot.com/2008/07/single-instance-from-your-application.html



                              I think it will be a help to those with a strict firewall setting.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered May 16 '09 at 12:53









                              IkonIkon

                              556714




                              556714













                              • Yes, it's a good way as the lock would be released event if the application crashed or so :)

                                – LE GALL Benoît
                                Jun 18 '15 at 14:45



















                              • Yes, it's a good way as the lock would be released event if the application crashed or so :)

                                – LE GALL Benoît
                                Jun 18 '15 at 14:45

















                              Yes, it's a good way as the lock would be released event if the application crashed or so :)

                              – LE GALL Benoît
                              Jun 18 '15 at 14:45





                              Yes, it's a good way as the lock would be released event if the application crashed or so :)

                              – LE GALL Benoît
                              Jun 18 '15 at 14:45











                              5














                              You can use JUnique library. It provides support for running single-instance java application and is open-source.



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




                              The JUnique library can be used to prevent a user to run at the same
                              time more instances of the same Java application.



                              JUnique implements locks and communication channels shared between all
                              the JVM instances launched by the same user.




                              public static void main(String args) {
                              String appId = "myapplicationid";
                              boolean alreadyRunning;
                              try {
                              JUnique.acquireLock(appId, new MessageHandler() {
                              public String handle(String message) {
                              // A brand new argument received! Handle it!
                              return null;
                              }
                              });
                              alreadyRunning = false;
                              } catch (AlreadyLockedException e) {
                              alreadyRunning = true;
                              }
                              if (!alreadyRunning) {
                              // Start sequence here
                              } else {
                              for (int i = 0; i < args.length; i++) {
                              JUnique.sendMessage(appId, args[0]));
                              }
                              }
                              }


                              Under the hood, it creates file locks in %USER_DATA%/.junique folder and creates a server socket at random port for each unique appId that allows sending/receiving messages between java applications.






                              share|improve this answer
























                              • Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                                – Wuaner
                                Apr 25 '17 at 2:29
















                              5














                              You can use JUnique library. It provides support for running single-instance java application and is open-source.



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




                              The JUnique library can be used to prevent a user to run at the same
                              time more instances of the same Java application.



                              JUnique implements locks and communication channels shared between all
                              the JVM instances launched by the same user.




                              public static void main(String args) {
                              String appId = "myapplicationid";
                              boolean alreadyRunning;
                              try {
                              JUnique.acquireLock(appId, new MessageHandler() {
                              public String handle(String message) {
                              // A brand new argument received! Handle it!
                              return null;
                              }
                              });
                              alreadyRunning = false;
                              } catch (AlreadyLockedException e) {
                              alreadyRunning = true;
                              }
                              if (!alreadyRunning) {
                              // Start sequence here
                              } else {
                              for (int i = 0; i < args.length; i++) {
                              JUnique.sendMessage(appId, args[0]));
                              }
                              }
                              }


                              Under the hood, it creates file locks in %USER_DATA%/.junique folder and creates a server socket at random port for each unique appId that allows sending/receiving messages between java applications.






                              share|improve this answer
























                              • Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                                – Wuaner
                                Apr 25 '17 at 2:29














                              5












                              5








                              5







                              You can use JUnique library. It provides support for running single-instance java application and is open-source.



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




                              The JUnique library can be used to prevent a user to run at the same
                              time more instances of the same Java application.



                              JUnique implements locks and communication channels shared between all
                              the JVM instances launched by the same user.




                              public static void main(String args) {
                              String appId = "myapplicationid";
                              boolean alreadyRunning;
                              try {
                              JUnique.acquireLock(appId, new MessageHandler() {
                              public String handle(String message) {
                              // A brand new argument received! Handle it!
                              return null;
                              }
                              });
                              alreadyRunning = false;
                              } catch (AlreadyLockedException e) {
                              alreadyRunning = true;
                              }
                              if (!alreadyRunning) {
                              // Start sequence here
                              } else {
                              for (int i = 0; i < args.length; i++) {
                              JUnique.sendMessage(appId, args[0]));
                              }
                              }
                              }


                              Under the hood, it creates file locks in %USER_DATA%/.junique folder and creates a server socket at random port for each unique appId that allows sending/receiving messages between java applications.






                              share|improve this answer













                              You can use JUnique library. It provides support for running single-instance java application and is open-source.



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




                              The JUnique library can be used to prevent a user to run at the same
                              time more instances of the same Java application.



                              JUnique implements locks and communication channels shared between all
                              the JVM instances launched by the same user.




                              public static void main(String args) {
                              String appId = "myapplicationid";
                              boolean alreadyRunning;
                              try {
                              JUnique.acquireLock(appId, new MessageHandler() {
                              public String handle(String message) {
                              // A brand new argument received! Handle it!
                              return null;
                              }
                              });
                              alreadyRunning = false;
                              } catch (AlreadyLockedException e) {
                              alreadyRunning = true;
                              }
                              if (!alreadyRunning) {
                              // Start sequence here
                              } else {
                              for (int i = 0; i < args.length; i++) {
                              JUnique.sendMessage(appId, args[0]));
                              }
                              }
                              }


                              Under the hood, it creates file locks in %USER_DATA%/.junique folder and creates a server socket at random port for each unique appId that allows sending/receiving messages between java applications.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 23 '16 at 11:31









                              kolobokkolobok

                              2,37032444




                              2,37032444













                              • Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                                – Wuaner
                                Apr 25 '17 at 2:29



















                              • Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                                – Wuaner
                                Apr 25 '17 at 2:29

















                              Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                              – Wuaner
                              Apr 25 '17 at 2:29





                              Can I using this to prevent multi instance of java application in a network? aka, only one instance of my application is allowed within my entire network

                              – Wuaner
                              Apr 25 '17 at 2:29











                              4














                              On Windows, you can use launch4j.






                              share|improve this answer




























                                4














                                On Windows, you can use launch4j.






                                share|improve this answer


























                                  4












                                  4








                                  4







                                  On Windows, you can use launch4j.






                                  share|improve this answer













                                  On Windows, you can use launch4j.







                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered Oct 7 '08 at 9:01









                                  Jacek SzymańskiJacek Szymański

                                  2,4491714




                                  2,4491714























                                      2














                                      ManagementFactory class supported in J2SE 5.0 or later detail



                                      but now i use J2SE 1.4 and I found this one http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ but I never test. What do you think about it?






                                      share|improve this answer
























                                      • I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                        – VonC
                                        Oct 7 '08 at 6:20
















                                      2














                                      ManagementFactory class supported in J2SE 5.0 or later detail



                                      but now i use J2SE 1.4 and I found this one http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ but I never test. What do you think about it?






                                      share|improve this answer
























                                      • I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                        – VonC
                                        Oct 7 '08 at 6:20














                                      2












                                      2








                                      2







                                      ManagementFactory class supported in J2SE 5.0 or later detail



                                      but now i use J2SE 1.4 and I found this one http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ but I never test. What do you think about it?






                                      share|improve this answer













                                      ManagementFactory class supported in J2SE 5.0 or later detail



                                      but now i use J2SE 1.4 and I found this one http://audiprimadhanty.wordpress.com/2008/06/30/ensuring-one-instance-of-application-running-at-one-time/ but I never test. What do you think about it?







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Oct 7 '08 at 6:02









                                      Fuangwith S.Fuangwith S.

                                      3,49973139




                                      3,49973139













                                      • I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                        – VonC
                                        Oct 7 '08 at 6:20



















                                      • I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                        – VonC
                                        Oct 7 '08 at 6:20

















                                      I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                      – VonC
                                      Oct 7 '08 at 6:20





                                      I believe it is essentially what is described in the first link of my answer above... rbgrn.net/blog/2008/05/java-single-application-instance.html

                                      – VonC
                                      Oct 7 '08 at 6:20











                                      2














                                      You could try using the Preferences API. It is platform independent.






                                      share|improve this answer
























                                      • I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                        – Cal
                                        Nov 1 '09 at 4:43











                                      • @Cal But the same issue is with file changing/locking/etc...don't you think?

                                        – Alex
                                        Oct 1 '13 at 11:26
















                                      2














                                      You could try using the Preferences API. It is platform independent.






                                      share|improve this answer
























                                      • I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                        – Cal
                                        Nov 1 '09 at 4:43











                                      • @Cal But the same issue is with file changing/locking/etc...don't you think?

                                        – Alex
                                        Oct 1 '13 at 11:26














                                      2












                                      2








                                      2







                                      You could try using the Preferences API. It is platform independent.






                                      share|improve this answer













                                      You could try using the Preferences API. It is platform independent.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Oct 7 '08 at 8:58









                                      JavamannJavamann

                                      2,56912121




                                      2,56912121













                                      • I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                        – Cal
                                        Nov 1 '09 at 4:43











                                      • @Cal But the same issue is with file changing/locking/etc...don't you think?

                                        – Alex
                                        Oct 1 '13 at 11:26



















                                      • I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                        – Cal
                                        Nov 1 '09 at 4:43











                                      • @Cal But the same issue is with file changing/locking/etc...don't you think?

                                        – Alex
                                        Oct 1 '13 at 11:26

















                                      I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                      – Cal
                                      Nov 1 '09 at 4:43





                                      I like this idea since the API is simple but maybe some virus scanners wouldn't like you changing the registry so you get similar problems as with using RMI on systems with a software firewall.... not sure.

                                      – Cal
                                      Nov 1 '09 at 4:43













                                      @Cal But the same issue is with file changing/locking/etc...don't you think?

                                      – Alex
                                      Oct 1 '13 at 11:26





                                      @Cal But the same issue is with file changing/locking/etc...don't you think?

                                      – Alex
                                      Oct 1 '13 at 11:26











                                      2














                                      A more generic way of limiting the number of instance's on a single machine, or even an entire network, is to use a multicast socket.



                                      Using a multicast socket, enables you to broadcast a message to any amount of instances of your application, some of which can be on physically remote machines across a corporate network.



                                      In this way you can enable many types of configurations, to control things like




                                      • One or Many instances per machine

                                      • One or Many instances per network (eg controlling installs on a client site)


                                      Java's multicast support is via java.net package with MulticastSocket & DatagramSocket being the main tools.



                                      Note: MulticastSocket's do not guarantee delivery of data packets, so you should use a tool built on top of multicast sockets like JGroups. JGroups does guarantee delivery of all data. It is one single jar file, with a very simple API.



                                      JGroups has been around a while, and has some impressive usages in industry, for example it underpins JBoss's clustering mechanism do broadcast data to all instance of a cluster.



                                      To use JGroups, to limit the number of instances of an app (on a machine or a network, lets say: to the number of licences a customer has bought) is conceptually very simple :




                                      • Upon startup of your application, each instance tries to join a named group eg "My Great App Group". You will have configured this group to allow 0, 1 or N members

                                      • When the group member count is greater than what you have configured for it.. your app should refuse to start up.






                                      share|improve this answer






























                                        2














                                        A more generic way of limiting the number of instance's on a single machine, or even an entire network, is to use a multicast socket.



                                        Using a multicast socket, enables you to broadcast a message to any amount of instances of your application, some of which can be on physically remote machines across a corporate network.



                                        In this way you can enable many types of configurations, to control things like




                                        • One or Many instances per machine

                                        • One or Many instances per network (eg controlling installs on a client site)


                                        Java's multicast support is via java.net package with MulticastSocket & DatagramSocket being the main tools.



                                        Note: MulticastSocket's do not guarantee delivery of data packets, so you should use a tool built on top of multicast sockets like JGroups. JGroups does guarantee delivery of all data. It is one single jar file, with a very simple API.



                                        JGroups has been around a while, and has some impressive usages in industry, for example it underpins JBoss's clustering mechanism do broadcast data to all instance of a cluster.



                                        To use JGroups, to limit the number of instances of an app (on a machine or a network, lets say: to the number of licences a customer has bought) is conceptually very simple :




                                        • Upon startup of your application, each instance tries to join a named group eg "My Great App Group". You will have configured this group to allow 0, 1 or N members

                                        • When the group member count is greater than what you have configured for it.. your app should refuse to start up.






                                        share|improve this answer




























                                          2












                                          2








                                          2







                                          A more generic way of limiting the number of instance's on a single machine, or even an entire network, is to use a multicast socket.



                                          Using a multicast socket, enables you to broadcast a message to any amount of instances of your application, some of which can be on physically remote machines across a corporate network.



                                          In this way you can enable many types of configurations, to control things like




                                          • One or Many instances per machine

                                          • One or Many instances per network (eg controlling installs on a client site)


                                          Java's multicast support is via java.net package with MulticastSocket & DatagramSocket being the main tools.



                                          Note: MulticastSocket's do not guarantee delivery of data packets, so you should use a tool built on top of multicast sockets like JGroups. JGroups does guarantee delivery of all data. It is one single jar file, with a very simple API.



                                          JGroups has been around a while, and has some impressive usages in industry, for example it underpins JBoss's clustering mechanism do broadcast data to all instance of a cluster.



                                          To use JGroups, to limit the number of instances of an app (on a machine or a network, lets say: to the number of licences a customer has bought) is conceptually very simple :




                                          • Upon startup of your application, each instance tries to join a named group eg "My Great App Group". You will have configured this group to allow 0, 1 or N members

                                          • When the group member count is greater than what you have configured for it.. your app should refuse to start up.






                                          share|improve this answer















                                          A more generic way of limiting the number of instance's on a single machine, or even an entire network, is to use a multicast socket.



                                          Using a multicast socket, enables you to broadcast a message to any amount of instances of your application, some of which can be on physically remote machines across a corporate network.



                                          In this way you can enable many types of configurations, to control things like




                                          • One or Many instances per machine

                                          • One or Many instances per network (eg controlling installs on a client site)


                                          Java's multicast support is via java.net package with MulticastSocket & DatagramSocket being the main tools.



                                          Note: MulticastSocket's do not guarantee delivery of data packets, so you should use a tool built on top of multicast sockets like JGroups. JGroups does guarantee delivery of all data. It is one single jar file, with a very simple API.



                                          JGroups has been around a while, and has some impressive usages in industry, for example it underpins JBoss's clustering mechanism do broadcast data to all instance of a cluster.



                                          To use JGroups, to limit the number of instances of an app (on a machine or a network, lets say: to the number of licences a customer has bought) is conceptually very simple :




                                          • Upon startup of your application, each instance tries to join a named group eg "My Great App Group". You will have configured this group to allow 0, 1 or N members

                                          • When the group member count is greater than what you have configured for it.. your app should refuse to start up.







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited May 21 '18 at 15:37

























                                          answered Apr 22 '16 at 8:53









                                          johnmjohnm

                                          7,07611330




                                          7,07611330























                                              1














                                              You can open a Memory Mapped File and then see if that file is OPEN already. if it is already open, you can return from main.



                                              Other ways is to use lock files(standard unix practice). One more way is to put something into the clipboard when main starts after checking if something is already in the clipboard.



                                              Else, you can open a socket in a listen mode(ServerSocket). First try to connect to hte socket ; if you cannot connect, then open a serversocket. if you connect, then you know that another instance is already running.



                                              So, pretty much any system resource can be used for knowing that an app is running.



                                              BR,
                                              ~A






                                              share|improve this answer
























                                              • do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                                – android developer
                                                Oct 2 '13 at 12:15
















                                              1














                                              You can open a Memory Mapped File and then see if that file is OPEN already. if it is already open, you can return from main.



                                              Other ways is to use lock files(standard unix practice). One more way is to put something into the clipboard when main starts after checking if something is already in the clipboard.



                                              Else, you can open a socket in a listen mode(ServerSocket). First try to connect to hte socket ; if you cannot connect, then open a serversocket. if you connect, then you know that another instance is already running.



                                              So, pretty much any system resource can be used for knowing that an app is running.



                                              BR,
                                              ~A






                                              share|improve this answer
























                                              • do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                                – android developer
                                                Oct 2 '13 at 12:15














                                              1












                                              1








                                              1







                                              You can open a Memory Mapped File and then see if that file is OPEN already. if it is already open, you can return from main.



                                              Other ways is to use lock files(standard unix practice). One more way is to put something into the clipboard when main starts after checking if something is already in the clipboard.



                                              Else, you can open a socket in a listen mode(ServerSocket). First try to connect to hte socket ; if you cannot connect, then open a serversocket. if you connect, then you know that another instance is already running.



                                              So, pretty much any system resource can be used for knowing that an app is running.



                                              BR,
                                              ~A






                                              share|improve this answer













                                              You can open a Memory Mapped File and then see if that file is OPEN already. if it is already open, you can return from main.



                                              Other ways is to use lock files(standard unix practice). One more way is to put something into the clipboard when main starts after checking if something is already in the clipboard.



                                              Else, you can open a socket in a listen mode(ServerSocket). First try to connect to hte socket ; if you cannot connect, then open a serversocket. if you connect, then you know that another instance is already running.



                                              So, pretty much any system resource can be used for knowing that an app is running.



                                              BR,
                                              ~A







                                              share|improve this answer












                                              share|improve this answer



                                              share|improve this answer










                                              answered Oct 7 '08 at 4:33









                                              anjanbanjanb

                                              7,477146091




                                              7,477146091













                                              • do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                                – android developer
                                                Oct 2 '13 at 12:15



















                                              • do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                                – android developer
                                                Oct 2 '13 at 12:15

















                                              do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                              – android developer
                                              Oct 2 '13 at 12:15





                                              do you have code for any of those ideas? also, what if i want that if the user starts a new instance, it will close all of the previous ones ?

                                              – android developer
                                              Oct 2 '13 at 12:15











                                              1














                                              I used sockets for that and depending if the application is on the client side or server side the behavior is a bit different:




                                              • client side : if an instance already exists(I cannot listen on a specific port) I will pass the application parameters and exit(you may want to perform some actions in the previous instance) if not I will start the application.

                                              • server side : if an instance already exists I will print a message and exit, if not I will start the application.






                                              share|improve this answer




























                                                1














                                                I used sockets for that and depending if the application is on the client side or server side the behavior is a bit different:




                                                • client side : if an instance already exists(I cannot listen on a specific port) I will pass the application parameters and exit(you may want to perform some actions in the previous instance) if not I will start the application.

                                                • server side : if an instance already exists I will print a message and exit, if not I will start the application.






                                                share|improve this answer


























                                                  1












                                                  1








                                                  1







                                                  I used sockets for that and depending if the application is on the client side or server side the behavior is a bit different:




                                                  • client side : if an instance already exists(I cannot listen on a specific port) I will pass the application parameters and exit(you may want to perform some actions in the previous instance) if not I will start the application.

                                                  • server side : if an instance already exists I will print a message and exit, if not I will start the application.






                                                  share|improve this answer













                                                  I used sockets for that and depending if the application is on the client side or server side the behavior is a bit different:




                                                  • client side : if an instance already exists(I cannot listen on a specific port) I will pass the application parameters and exit(you may want to perform some actions in the previous instance) if not I will start the application.

                                                  • server side : if an instance already exists I will print a message and exit, if not I will start the application.







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered May 16 '09 at 19:49









                                                  adrian.tarauadrian.tarau

                                                  2,68922029




                                                  2,68922029























                                                      1
















                                                      public class SingleInstance {
                                                      public static final String LOCK = System.getProperty("user.home") + File.separator + "test.lock";
                                                      public static final String PIPE = System.getProperty("user.home") + File.separator + "test.pipe";
                                                      private static JFrame frame = null;

                                                      public static void main(String args) {
                                                      try {
                                                      FileChannel lockChannel = new RandomAccessFile(LOCK, "rw").getChannel();
                                                      FileLock flk = null;
                                                      try {
                                                      flk = lockChannel.tryLock();
                                                      } catch(Throwable t) {
                                                      t.printStackTrace();
                                                      }
                                                      if (flk == null || !flk.isValid()) {
                                                      System.out.println("alread running, leaving a message to pipe and quitting...");
                                                      FileChannel pipeChannel = null;
                                                      try {
                                                      pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                      MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                      bb.put(0, (byte)1);
                                                      bb.force();
                                                      } catch (Throwable t) {
                                                      t.printStackTrace();
                                                      } finally {
                                                      if (pipeChannel != null) {
                                                      try {
                                                      pipeChannel.close();
                                                      } catch (Throwable t) {
                                                      t.printStackTrace();
                                                      }
                                                      }
                                                      }
                                                      System.exit(0);
                                                      }
                                                      //We do not release the lock and close the channel here,
                                                      // which will be done after the application crashes or closes normally.
                                                      SwingUtilities.invokeLater(
                                                      new Runnable() {
                                                      public void run() {
                                                      createAndShowGUI();
                                                      }
                                                      }
                                                      );

                                                      FileChannel pipeChannel = null;
                                                      try {
                                                      pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                      MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                      while (true) {
                                                      byte b = bb.get(0);
                                                      if (b > 0) {
                                                      bb.put(0, (byte)0);
                                                      bb.force();
                                                      SwingUtilities.invokeLater(
                                                      new Runnable() {
                                                      public void run() {
                                                      frame.setExtendedState(JFrame.NORMAL);
                                                      frame.setAlwaysOnTop(true);
                                                      frame.toFront();
                                                      frame.setAlwaysOnTop(false);
                                                      }
                                                      }
                                                      );
                                                      }
                                                      Thread.sleep(1000);
                                                      }
                                                      } catch (Throwable t) {
                                                      t.printStackTrace();
                                                      } finally {
                                                      if (pipeChannel != null) {
                                                      try {
                                                      pipeChannel.close();
                                                      } catch (Throwable t) {
                                                      t.printStackTrace();
                                                      }
                                                      }
                                                      }
                                                      } catch(Throwable t) {
                                                      t.printStackTrace();
                                                      }
                                                      }

                                                      public static void createAndShowGUI() {

                                                      frame = new JFrame();
                                                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                                      frame.setSize(800, 650);
                                                      frame.getContentPane().add(new JLabel("MAIN WINDOW",
                                                      SwingConstants.CENTER), BorderLayout.CENTER);
                                                      frame.setLocationRelativeTo(null);
                                                      frame.setVisible(true);
                                                      }
                                                      }






                                                      share|improve this answer




























                                                        1
















                                                        public class SingleInstance {
                                                        public static final String LOCK = System.getProperty("user.home") + File.separator + "test.lock";
                                                        public static final String PIPE = System.getProperty("user.home") + File.separator + "test.pipe";
                                                        private static JFrame frame = null;

                                                        public static void main(String args) {
                                                        try {
                                                        FileChannel lockChannel = new RandomAccessFile(LOCK, "rw").getChannel();
                                                        FileLock flk = null;
                                                        try {
                                                        flk = lockChannel.tryLock();
                                                        } catch(Throwable t) {
                                                        t.printStackTrace();
                                                        }
                                                        if (flk == null || !flk.isValid()) {
                                                        System.out.println("alread running, leaving a message to pipe and quitting...");
                                                        FileChannel pipeChannel = null;
                                                        try {
                                                        pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                        MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                        bb.put(0, (byte)1);
                                                        bb.force();
                                                        } catch (Throwable t) {
                                                        t.printStackTrace();
                                                        } finally {
                                                        if (pipeChannel != null) {
                                                        try {
                                                        pipeChannel.close();
                                                        } catch (Throwable t) {
                                                        t.printStackTrace();
                                                        }
                                                        }
                                                        }
                                                        System.exit(0);
                                                        }
                                                        //We do not release the lock and close the channel here,
                                                        // which will be done after the application crashes or closes normally.
                                                        SwingUtilities.invokeLater(
                                                        new Runnable() {
                                                        public void run() {
                                                        createAndShowGUI();
                                                        }
                                                        }
                                                        );

                                                        FileChannel pipeChannel = null;
                                                        try {
                                                        pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                        MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                        while (true) {
                                                        byte b = bb.get(0);
                                                        if (b > 0) {
                                                        bb.put(0, (byte)0);
                                                        bb.force();
                                                        SwingUtilities.invokeLater(
                                                        new Runnable() {
                                                        public void run() {
                                                        frame.setExtendedState(JFrame.NORMAL);
                                                        frame.setAlwaysOnTop(true);
                                                        frame.toFront();
                                                        frame.setAlwaysOnTop(false);
                                                        }
                                                        }
                                                        );
                                                        }
                                                        Thread.sleep(1000);
                                                        }
                                                        } catch (Throwable t) {
                                                        t.printStackTrace();
                                                        } finally {
                                                        if (pipeChannel != null) {
                                                        try {
                                                        pipeChannel.close();
                                                        } catch (Throwable t) {
                                                        t.printStackTrace();
                                                        }
                                                        }
                                                        }
                                                        } catch(Throwable t) {
                                                        t.printStackTrace();
                                                        }
                                                        }

                                                        public static void createAndShowGUI() {

                                                        frame = new JFrame();
                                                        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                                        frame.setSize(800, 650);
                                                        frame.getContentPane().add(new JLabel("MAIN WINDOW",
                                                        SwingConstants.CENTER), BorderLayout.CENTER);
                                                        frame.setLocationRelativeTo(null);
                                                        frame.setVisible(true);
                                                        }
                                                        }






                                                        share|improve this answer


























                                                          1












                                                          1








                                                          1









                                                          public class SingleInstance {
                                                          public static final String LOCK = System.getProperty("user.home") + File.separator + "test.lock";
                                                          public static final String PIPE = System.getProperty("user.home") + File.separator + "test.pipe";
                                                          private static JFrame frame = null;

                                                          public static void main(String args) {
                                                          try {
                                                          FileChannel lockChannel = new RandomAccessFile(LOCK, "rw").getChannel();
                                                          FileLock flk = null;
                                                          try {
                                                          flk = lockChannel.tryLock();
                                                          } catch(Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          if (flk == null || !flk.isValid()) {
                                                          System.out.println("alread running, leaving a message to pipe and quitting...");
                                                          FileChannel pipeChannel = null;
                                                          try {
                                                          pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                          MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                          bb.put(0, (byte)1);
                                                          bb.force();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          } finally {
                                                          if (pipeChannel != null) {
                                                          try {
                                                          pipeChannel.close();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }
                                                          }
                                                          System.exit(0);
                                                          }
                                                          //We do not release the lock and close the channel here,
                                                          // which will be done after the application crashes or closes normally.
                                                          SwingUtilities.invokeLater(
                                                          new Runnable() {
                                                          public void run() {
                                                          createAndShowGUI();
                                                          }
                                                          }
                                                          );

                                                          FileChannel pipeChannel = null;
                                                          try {
                                                          pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                          MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                          while (true) {
                                                          byte b = bb.get(0);
                                                          if (b > 0) {
                                                          bb.put(0, (byte)0);
                                                          bb.force();
                                                          SwingUtilities.invokeLater(
                                                          new Runnable() {
                                                          public void run() {
                                                          frame.setExtendedState(JFrame.NORMAL);
                                                          frame.setAlwaysOnTop(true);
                                                          frame.toFront();
                                                          frame.setAlwaysOnTop(false);
                                                          }
                                                          }
                                                          );
                                                          }
                                                          Thread.sleep(1000);
                                                          }
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          } finally {
                                                          if (pipeChannel != null) {
                                                          try {
                                                          pipeChannel.close();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }
                                                          }
                                                          } catch(Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }

                                                          public static void createAndShowGUI() {

                                                          frame = new JFrame();
                                                          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                                          frame.setSize(800, 650);
                                                          frame.getContentPane().add(new JLabel("MAIN WINDOW",
                                                          SwingConstants.CENTER), BorderLayout.CENTER);
                                                          frame.setLocationRelativeTo(null);
                                                          frame.setVisible(true);
                                                          }
                                                          }






                                                          share|improve this answer















                                                          public class SingleInstance {
                                                          public static final String LOCK = System.getProperty("user.home") + File.separator + "test.lock";
                                                          public static final String PIPE = System.getProperty("user.home") + File.separator + "test.pipe";
                                                          private static JFrame frame = null;

                                                          public static void main(String args) {
                                                          try {
                                                          FileChannel lockChannel = new RandomAccessFile(LOCK, "rw").getChannel();
                                                          FileLock flk = null;
                                                          try {
                                                          flk = lockChannel.tryLock();
                                                          } catch(Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          if (flk == null || !flk.isValid()) {
                                                          System.out.println("alread running, leaving a message to pipe and quitting...");
                                                          FileChannel pipeChannel = null;
                                                          try {
                                                          pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                          MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                          bb.put(0, (byte)1);
                                                          bb.force();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          } finally {
                                                          if (pipeChannel != null) {
                                                          try {
                                                          pipeChannel.close();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }
                                                          }
                                                          System.exit(0);
                                                          }
                                                          //We do not release the lock and close the channel here,
                                                          // which will be done after the application crashes or closes normally.
                                                          SwingUtilities.invokeLater(
                                                          new Runnable() {
                                                          public void run() {
                                                          createAndShowGUI();
                                                          }
                                                          }
                                                          );

                                                          FileChannel pipeChannel = null;
                                                          try {
                                                          pipeChannel = new RandomAccessFile(PIPE, "rw").getChannel();
                                                          MappedByteBuffer bb = pipeChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1);
                                                          while (true) {
                                                          byte b = bb.get(0);
                                                          if (b > 0) {
                                                          bb.put(0, (byte)0);
                                                          bb.force();
                                                          SwingUtilities.invokeLater(
                                                          new Runnable() {
                                                          public void run() {
                                                          frame.setExtendedState(JFrame.NORMAL);
                                                          frame.setAlwaysOnTop(true);
                                                          frame.toFront();
                                                          frame.setAlwaysOnTop(false);
                                                          }
                                                          }
                                                          );
                                                          }
                                                          Thread.sleep(1000);
                                                          }
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          } finally {
                                                          if (pipeChannel != null) {
                                                          try {
                                                          pipeChannel.close();
                                                          } catch (Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }
                                                          }
                                                          } catch(Throwable t) {
                                                          t.printStackTrace();
                                                          }
                                                          }

                                                          public static void createAndShowGUI() {

                                                          frame = new JFrame();
                                                          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                                                          frame.setSize(800, 650);
                                                          frame.getContentPane().add(new JLabel("MAIN WINDOW",
                                                          SwingConstants.CENTER), BorderLayout.CENTER);
                                                          frame.setLocationRelativeTo(null);
                                                          frame.setVisible(true);
                                                          }
                                                          }







                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered May 12 '14 at 16:13









                                                          GeorgeGeorge

                                                          111




                                                          111























                                                              0














                                                              EDIT: Instead of using this WatchService approach, a simple 1 second timer thread could be used to check if the indicatorFile.exists(). Delete it, then bring the application toFront().



                                                              EDIT: I would like to know why this was downvoted. It's the best solution I have seen so far. E.g. the server socket approach fails if another application happens to already be listening to the port.



                                                              Just download Microsoft Windows Sysinternals TCPView (or use netstat), start it, sort by "State", look for the line block that says "LISTENING", pick one whose remote address says your computer's name, put that port into your new-Socket()-solution. In my implementation of it, I can produce failure every time. And it's logical, because it's the very foundation of the approach. Or what am I not getting regarding how to implement this?



                                                              Please inform me if and how I am wrong about this!



                                                              My view - which I am asking you to disprove if possible - is that developers are being advised to use an approach in production code that will fail in at least 1 of about 60000 cases. And if this view happens to be correct, then it can absolutely not be that a solution presented that does not have this problem is downvoted and criticized for its amount of code.



                                                              Disadvantages of the socket approach in comparison:




                                                              • Fails if the wrong lottery ticket (port number) is chosen.

                                                              • Fails in multi user environment: Only one user can run the application at the same time. (My approach would have to be slightly changed to create the file(s) in the user tree, but that's trivial.)

                                                              • Fails if firewall rules are too strict.

                                                              • Makes suspicious users (which I did meet in the wild) wonder what shenanigans you're up to when your text editor is claiming a server socket.




                                                              I just had a nice idea for how to solve the new-instance-to-existing-instance Java communication problem in a way that should work on every system. So, I whipped up this class in about two hours. Works like a charm :D



                                                              It's based on Robert's file lock approach (also on this page), which I have used ever since. To tell the already running instance that another instance tried to start (but didn't) ... a file is created and immediately deleted, and the first instance uses the WatchService to detect this folder content change. I can't believe that apparently this is a new idea, given how fundamental the problem is.



                                                              This can easily be changed to just create and not delete the file, and then information can be put into it that the proper instance can evaluate, e.g. the command line arguments - and the proper instance can then perform the deletion. Personally, I only needed to know when to restore my application's window and send it to front.



                                                              Example use:



                                                              public static void main(final String args) {

                                                              // ENSURE SINGLE INSTANCE
                                                              if (!SingleInstanceChecker.INSTANCE.isOnlyInstance(Main::otherInstanceTriedToLaunch, false)) {
                                                              System.exit(0);
                                                              }

                                                              // launch rest of application here
                                                              System.out.println("Application starts properly because it's the only instance.");
                                                              }

                                                              private static void otherInstanceTriedToLaunch() {
                                                              // Restore your application window and bring it to front.
                                                              // But make sure your situation is apt: This method could be called at *any* time.
                                                              System.err.println("Deiconified because other instance tried to start.");
                                                              }


                                                              Here's the class:



                                                              package yourpackagehere;

                                                              import javax.swing.*;
                                                              import java.io.File;
                                                              import java.io.IOException;
                                                              import java.io.RandomAccessFile;
                                                              import java.nio.channels.FileLock;
                                                              import java.nio.file.*;




                                                              /**
                                                              * SingleInstanceChecker v[(2), 2016-04-22 08:00 UTC] by dreamspace-president.com
                                                              * <p>
                                                              * (file lock single instance solution by Robert https://stackoverflow.com/a/2002948/3500521)
                                                              */
                                                              public enum SingleInstanceChecker {

                                                              INSTANCE; // HAHA! The CONFUSION!


                                                              final public static int POLLINTERVAL = 1000;
                                                              final public static File LOCKFILE = new File("SINGLE_INSTANCE_LOCKFILE");
                                                              final public static File DETECTFILE = new File("EXTRA_INSTANCE_DETECTFILE");


                                                              private boolean hasBeenUsedAlready = false;


                                                              private WatchService watchService = null;
                                                              private RandomAccessFile randomAccessFileForLock = null;
                                                              private FileLock fileLock = null;


                                                              /**
                                                              * CAN ONLY BE CALLED ONCE.
                                                              * <p>
                                                              * Assumes that the program will close if FALSE is returned: The other-instance-tries-to-launch listener is not
                                                              * installed in that case.
                                                              * <p>
                                                              * Checks if another instance is already running (temp file lock / shutdownhook). Depending on the accessibility of
                                                              * the temp file the return value will be true or false. This approach even works even if the virtual machine
                                                              * process gets killed. On the next run, the program can even detect if it has shut down irregularly, because then
                                                              * the file will still exist. (Thanks to Robert https://stackoverflow.com/a/2002948/3500521 for that solution!)
                                                              * <p>
                                                              * Additionally, the method checks if another instance tries to start. In a crappy way, because as awesome as Java
                                                              * is, it lacks some fundamental features. Don't worry, it has only been 25 years, it'll sure come eventually.
                                                              *
                                                              * @param codeToRunIfOtherInstanceTriesToStart Can be null. If not null and another instance tries to start (which
                                                              * changes the detect-file), the code will be executed. Could be used to
                                                              * bring the current (=old=only) instance to front. If null, then the
                                                              * watcher will not be installed at all, nor will the trigger file be
                                                              * created. (Null means that you just don't want to make use of this
                                                              * half of the class' purpose, but then you would be better advised to
                                                              * just use the 24 line method by Robert.)
                                                              * <p>
                                                              * BE CAREFUL with the code: It will potentially be called until the
                                                              * very last moment of the program's existence, so if you e.g. have a
                                                              * shutdown procedure or a window that would be brought to front, check
                                                              * if the procedure has not been triggered yet or if the window still
                                                              * exists / hasn't been disposed of yet. Or edit this class to be more
                                                              * comfortable. This would e.g. allow you to remove some crappy
                                                              * comments. Attribution would be nice, though.
                                                              * @param executeOnAWTEventDispatchThread Convenience function. If false, the code will just be executed. If
                                                              * true, it will be detected if we're currently on that thread. If so,
                                                              * the code will just be executed. If not so, the code will be run via
                                                              * SwingUtilities.invokeLater().
                                                              * @return if this is the only instance
                                                              */
                                                              public boolean isOnlyInstance(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              if (hasBeenUsedAlready) {
                                                              throw new IllegalStateException("This class/method can only be used once, which kinda makes sense if you think about it.");
                                                              }
                                                              hasBeenUsedAlready = true;

                                                              final boolean ret = canLockFileBeCreatedAndLocked();

                                                              if (codeToRunIfOtherInstanceTriesToStart != null) {
                                                              if (ret) {
                                                              // Only if this is the only instance, it makes sense to install a watcher for additional instances.
                                                              installOtherInstanceLaunchAttemptWatcher(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread);
                                                              } else {
                                                              // Only if this is NOT the only instance, it makes sense to create&delete the trigger file that will effect notification of the other instance.
                                                              //
                                                              // Regarding "codeToRunIfOtherInstanceTriesToStart != null":
                                                              // While creation/deletion of the file concerns THE OTHER instance of the program,
                                                              // making it dependent on the call made in THIS instance makes sense
                                                              // because the code executed is probably the same.
                                                              createAndDeleteOtherInstanceWatcherTriggerFile();
                                                              }
                                                              }

                                                              optionallyInstallShutdownHookThatCleansEverythingUp();

                                                              return ret;
                                                              }


                                                              private void createAndDeleteOtherInstanceWatcherTriggerFile() {

                                                              try {
                                                              final RandomAccessFile randomAccessFileForDetection = new RandomAccessFile(DETECTFILE, "rw");
                                                              randomAccessFileForDetection.close();
                                                              Files.deleteIfExists(DETECTFILE.toPath()); // File is created and then instantly deleted. Not a problem for the WatchService :)
                                                              } catch (Exception e) {
                                                              e.printStackTrace();
                                                              }
                                                              }


                                                              private boolean canLockFileBeCreatedAndLocked() {

                                                              try {
                                                              randomAccessFileForLock = new RandomAccessFile(LOCKFILE, "rw");
                                                              fileLock = randomAccessFileForLock.getChannel().tryLock();
                                                              return fileLock != null;
                                                              } catch (Exception e) {
                                                              return false;
                                                              }
                                                              }


                                                              private void installOtherInstanceLaunchAttemptWatcher(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              // PREPARE WATCHSERVICE AND STUFF
                                                              try {
                                                              watchService = FileSystems.getDefault().newWatchService();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }
                                                              final File appFolder = new File("").getAbsoluteFile(); // points to current folder
                                                              final Path appFolderWatchable = appFolder.toPath();


                                                              // REGISTER CURRENT FOLDER FOR WATCHING FOR FILE DELETIONS
                                                              try {
                                                              appFolderWatchable.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }


                                                              // INSTALL WATCHER THAT LOOKS IF OUR detectFile SHOWS UP IN THE DIRECTORY CHANGES. IF THERE'S A CHANGE, ANOTHER INSTANCE TRIED TO START, SO NOTIFY THE CURRENT ONE OF THAT.
                                                              final Thread t = new Thread(() -> watchForDirectoryChangesOnExtraThread(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread));
                                                              t.setDaemon(true);
                                                              t.setName("directory content change watcher");
                                                              t.start();
                                                              }


                                                              private void optionallyInstallShutdownHookThatCleansEverythingUp() {

                                                              if (fileLock == null && randomAccessFileForLock == null && watchService == null) {
                                                              return;
                                                              }

                                                              final Thread shutdownHookThread = new Thread(() -> {
                                                              try {
                                                              if (fileLock != null) {
                                                              fileLock.release();
                                                              }
                                                              if (randomAccessFileForLock != null) {
                                                              randomAccessFileForLock.close();
                                                              }
                                                              Files.deleteIfExists(LOCKFILE.toPath());
                                                              } catch (Exception ignore) {
                                                              }
                                                              if (watchService != null) {
                                                              try {
                                                              watchService.close();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              }
                                                              }
                                                              });
                                                              Runtime.getRuntime().addShutdownHook(shutdownHookThread);
                                                              }


                                                              private void watchForDirectoryChangesOnExtraThread(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              while (true) { // To eternity and beyond! Until the universe shuts down. (Should be a volatile boolean, but this class only has absolutely required features.)

                                                              try {
                                                              Thread.sleep(POLLINTERVAL);
                                                              } catch (InterruptedException e) {
                                                              e.printStackTrace();
                                                              }


                                                              final WatchKey wk;
                                                              try {
                                                              wk = watchService.poll();
                                                              } catch (ClosedWatchServiceException e) {
                                                              // This situation would be normal if the watcher has been closed, but our application never does that.
                                                              e.printStackTrace();
                                                              return;
                                                              }

                                                              if (wk == null || !wk.isValid()) {
                                                              continue;
                                                              }


                                                              for (WatchEvent<?> we : wk.pollEvents()) {

                                                              final WatchEvent.Kind<?> kind = we.kind();
                                                              if (kind == StandardWatchEventKinds.OVERFLOW) {
                                                              System.err.println("OVERFLOW of directory change events!");
                                                              continue;
                                                              }


                                                              final WatchEvent<Path> watchEvent = (WatchEvent<Path>) we;
                                                              final File file = watchEvent.context().toFile();


                                                              if (file.equals(DETECTFILE)) {

                                                              if (!executeOnAWTEventDispatchThread || SwingUtilities.isEventDispatchThread()) {
                                                              codeToRunIfOtherInstanceTriesToStart.run();
                                                              } else {
                                                              SwingUtilities.invokeLater(codeToRunIfOtherInstanceTriesToStart);
                                                              }

                                                              break;

                                                              } else {
                                                              System.err.println("THIS IS THE FILE THAT WAS DELETED: " + file);
                                                              }

                                                              }

                                                              wk.reset();
                                                              }
                                                              }

                                                              }





                                                              share|improve this answer


























                                                              • You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                                – user207421
                                                                Apr 22 '16 at 8:30











                                                              • @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                                – Dreamspace President
                                                                Apr 22 '16 at 12:45











                                                              • @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:26











                                                              • @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:34











                                                              • @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                                – Dreamspace President
                                                                May 4 '16 at 12:45


















                                                              0














                                                              EDIT: Instead of using this WatchService approach, a simple 1 second timer thread could be used to check if the indicatorFile.exists(). Delete it, then bring the application toFront().



                                                              EDIT: I would like to know why this was downvoted. It's the best solution I have seen so far. E.g. the server socket approach fails if another application happens to already be listening to the port.



                                                              Just download Microsoft Windows Sysinternals TCPView (or use netstat), start it, sort by "State", look for the line block that says "LISTENING", pick one whose remote address says your computer's name, put that port into your new-Socket()-solution. In my implementation of it, I can produce failure every time. And it's logical, because it's the very foundation of the approach. Or what am I not getting regarding how to implement this?



                                                              Please inform me if and how I am wrong about this!



                                                              My view - which I am asking you to disprove if possible - is that developers are being advised to use an approach in production code that will fail in at least 1 of about 60000 cases. And if this view happens to be correct, then it can absolutely not be that a solution presented that does not have this problem is downvoted and criticized for its amount of code.



                                                              Disadvantages of the socket approach in comparison:




                                                              • Fails if the wrong lottery ticket (port number) is chosen.

                                                              • Fails in multi user environment: Only one user can run the application at the same time. (My approach would have to be slightly changed to create the file(s) in the user tree, but that's trivial.)

                                                              • Fails if firewall rules are too strict.

                                                              • Makes suspicious users (which I did meet in the wild) wonder what shenanigans you're up to when your text editor is claiming a server socket.




                                                              I just had a nice idea for how to solve the new-instance-to-existing-instance Java communication problem in a way that should work on every system. So, I whipped up this class in about two hours. Works like a charm :D



                                                              It's based on Robert's file lock approach (also on this page), which I have used ever since. To tell the already running instance that another instance tried to start (but didn't) ... a file is created and immediately deleted, and the first instance uses the WatchService to detect this folder content change. I can't believe that apparently this is a new idea, given how fundamental the problem is.



                                                              This can easily be changed to just create and not delete the file, and then information can be put into it that the proper instance can evaluate, e.g. the command line arguments - and the proper instance can then perform the deletion. Personally, I only needed to know when to restore my application's window and send it to front.



                                                              Example use:



                                                              public static void main(final String args) {

                                                              // ENSURE SINGLE INSTANCE
                                                              if (!SingleInstanceChecker.INSTANCE.isOnlyInstance(Main::otherInstanceTriedToLaunch, false)) {
                                                              System.exit(0);
                                                              }

                                                              // launch rest of application here
                                                              System.out.println("Application starts properly because it's the only instance.");
                                                              }

                                                              private static void otherInstanceTriedToLaunch() {
                                                              // Restore your application window and bring it to front.
                                                              // But make sure your situation is apt: This method could be called at *any* time.
                                                              System.err.println("Deiconified because other instance tried to start.");
                                                              }


                                                              Here's the class:



                                                              package yourpackagehere;

                                                              import javax.swing.*;
                                                              import java.io.File;
                                                              import java.io.IOException;
                                                              import java.io.RandomAccessFile;
                                                              import java.nio.channels.FileLock;
                                                              import java.nio.file.*;




                                                              /**
                                                              * SingleInstanceChecker v[(2), 2016-04-22 08:00 UTC] by dreamspace-president.com
                                                              * <p>
                                                              * (file lock single instance solution by Robert https://stackoverflow.com/a/2002948/3500521)
                                                              */
                                                              public enum SingleInstanceChecker {

                                                              INSTANCE; // HAHA! The CONFUSION!


                                                              final public static int POLLINTERVAL = 1000;
                                                              final public static File LOCKFILE = new File("SINGLE_INSTANCE_LOCKFILE");
                                                              final public static File DETECTFILE = new File("EXTRA_INSTANCE_DETECTFILE");


                                                              private boolean hasBeenUsedAlready = false;


                                                              private WatchService watchService = null;
                                                              private RandomAccessFile randomAccessFileForLock = null;
                                                              private FileLock fileLock = null;


                                                              /**
                                                              * CAN ONLY BE CALLED ONCE.
                                                              * <p>
                                                              * Assumes that the program will close if FALSE is returned: The other-instance-tries-to-launch listener is not
                                                              * installed in that case.
                                                              * <p>
                                                              * Checks if another instance is already running (temp file lock / shutdownhook). Depending on the accessibility of
                                                              * the temp file the return value will be true or false. This approach even works even if the virtual machine
                                                              * process gets killed. On the next run, the program can even detect if it has shut down irregularly, because then
                                                              * the file will still exist. (Thanks to Robert https://stackoverflow.com/a/2002948/3500521 for that solution!)
                                                              * <p>
                                                              * Additionally, the method checks if another instance tries to start. In a crappy way, because as awesome as Java
                                                              * is, it lacks some fundamental features. Don't worry, it has only been 25 years, it'll sure come eventually.
                                                              *
                                                              * @param codeToRunIfOtherInstanceTriesToStart Can be null. If not null and another instance tries to start (which
                                                              * changes the detect-file), the code will be executed. Could be used to
                                                              * bring the current (=old=only) instance to front. If null, then the
                                                              * watcher will not be installed at all, nor will the trigger file be
                                                              * created. (Null means that you just don't want to make use of this
                                                              * half of the class' purpose, but then you would be better advised to
                                                              * just use the 24 line method by Robert.)
                                                              * <p>
                                                              * BE CAREFUL with the code: It will potentially be called until the
                                                              * very last moment of the program's existence, so if you e.g. have a
                                                              * shutdown procedure or a window that would be brought to front, check
                                                              * if the procedure has not been triggered yet or if the window still
                                                              * exists / hasn't been disposed of yet. Or edit this class to be more
                                                              * comfortable. This would e.g. allow you to remove some crappy
                                                              * comments. Attribution would be nice, though.
                                                              * @param executeOnAWTEventDispatchThread Convenience function. If false, the code will just be executed. If
                                                              * true, it will be detected if we're currently on that thread. If so,
                                                              * the code will just be executed. If not so, the code will be run via
                                                              * SwingUtilities.invokeLater().
                                                              * @return if this is the only instance
                                                              */
                                                              public boolean isOnlyInstance(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              if (hasBeenUsedAlready) {
                                                              throw new IllegalStateException("This class/method can only be used once, which kinda makes sense if you think about it.");
                                                              }
                                                              hasBeenUsedAlready = true;

                                                              final boolean ret = canLockFileBeCreatedAndLocked();

                                                              if (codeToRunIfOtherInstanceTriesToStart != null) {
                                                              if (ret) {
                                                              // Only if this is the only instance, it makes sense to install a watcher for additional instances.
                                                              installOtherInstanceLaunchAttemptWatcher(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread);
                                                              } else {
                                                              // Only if this is NOT the only instance, it makes sense to create&delete the trigger file that will effect notification of the other instance.
                                                              //
                                                              // Regarding "codeToRunIfOtherInstanceTriesToStart != null":
                                                              // While creation/deletion of the file concerns THE OTHER instance of the program,
                                                              // making it dependent on the call made in THIS instance makes sense
                                                              // because the code executed is probably the same.
                                                              createAndDeleteOtherInstanceWatcherTriggerFile();
                                                              }
                                                              }

                                                              optionallyInstallShutdownHookThatCleansEverythingUp();

                                                              return ret;
                                                              }


                                                              private void createAndDeleteOtherInstanceWatcherTriggerFile() {

                                                              try {
                                                              final RandomAccessFile randomAccessFileForDetection = new RandomAccessFile(DETECTFILE, "rw");
                                                              randomAccessFileForDetection.close();
                                                              Files.deleteIfExists(DETECTFILE.toPath()); // File is created and then instantly deleted. Not a problem for the WatchService :)
                                                              } catch (Exception e) {
                                                              e.printStackTrace();
                                                              }
                                                              }


                                                              private boolean canLockFileBeCreatedAndLocked() {

                                                              try {
                                                              randomAccessFileForLock = new RandomAccessFile(LOCKFILE, "rw");
                                                              fileLock = randomAccessFileForLock.getChannel().tryLock();
                                                              return fileLock != null;
                                                              } catch (Exception e) {
                                                              return false;
                                                              }
                                                              }


                                                              private void installOtherInstanceLaunchAttemptWatcher(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              // PREPARE WATCHSERVICE AND STUFF
                                                              try {
                                                              watchService = FileSystems.getDefault().newWatchService();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }
                                                              final File appFolder = new File("").getAbsoluteFile(); // points to current folder
                                                              final Path appFolderWatchable = appFolder.toPath();


                                                              // REGISTER CURRENT FOLDER FOR WATCHING FOR FILE DELETIONS
                                                              try {
                                                              appFolderWatchable.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }


                                                              // INSTALL WATCHER THAT LOOKS IF OUR detectFile SHOWS UP IN THE DIRECTORY CHANGES. IF THERE'S A CHANGE, ANOTHER INSTANCE TRIED TO START, SO NOTIFY THE CURRENT ONE OF THAT.
                                                              final Thread t = new Thread(() -> watchForDirectoryChangesOnExtraThread(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread));
                                                              t.setDaemon(true);
                                                              t.setName("directory content change watcher");
                                                              t.start();
                                                              }


                                                              private void optionallyInstallShutdownHookThatCleansEverythingUp() {

                                                              if (fileLock == null && randomAccessFileForLock == null && watchService == null) {
                                                              return;
                                                              }

                                                              final Thread shutdownHookThread = new Thread(() -> {
                                                              try {
                                                              if (fileLock != null) {
                                                              fileLock.release();
                                                              }
                                                              if (randomAccessFileForLock != null) {
                                                              randomAccessFileForLock.close();
                                                              }
                                                              Files.deleteIfExists(LOCKFILE.toPath());
                                                              } catch (Exception ignore) {
                                                              }
                                                              if (watchService != null) {
                                                              try {
                                                              watchService.close();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              }
                                                              }
                                                              });
                                                              Runtime.getRuntime().addShutdownHook(shutdownHookThread);
                                                              }


                                                              private void watchForDirectoryChangesOnExtraThread(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              while (true) { // To eternity and beyond! Until the universe shuts down. (Should be a volatile boolean, but this class only has absolutely required features.)

                                                              try {
                                                              Thread.sleep(POLLINTERVAL);
                                                              } catch (InterruptedException e) {
                                                              e.printStackTrace();
                                                              }


                                                              final WatchKey wk;
                                                              try {
                                                              wk = watchService.poll();
                                                              } catch (ClosedWatchServiceException e) {
                                                              // This situation would be normal if the watcher has been closed, but our application never does that.
                                                              e.printStackTrace();
                                                              return;
                                                              }

                                                              if (wk == null || !wk.isValid()) {
                                                              continue;
                                                              }


                                                              for (WatchEvent<?> we : wk.pollEvents()) {

                                                              final WatchEvent.Kind<?> kind = we.kind();
                                                              if (kind == StandardWatchEventKinds.OVERFLOW) {
                                                              System.err.println("OVERFLOW of directory change events!");
                                                              continue;
                                                              }


                                                              final WatchEvent<Path> watchEvent = (WatchEvent<Path>) we;
                                                              final File file = watchEvent.context().toFile();


                                                              if (file.equals(DETECTFILE)) {

                                                              if (!executeOnAWTEventDispatchThread || SwingUtilities.isEventDispatchThread()) {
                                                              codeToRunIfOtherInstanceTriesToStart.run();
                                                              } else {
                                                              SwingUtilities.invokeLater(codeToRunIfOtherInstanceTriesToStart);
                                                              }

                                                              break;

                                                              } else {
                                                              System.err.println("THIS IS THE FILE THAT WAS DELETED: " + file);
                                                              }

                                                              }

                                                              wk.reset();
                                                              }
                                                              }

                                                              }





                                                              share|improve this answer


























                                                              • You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                                – user207421
                                                                Apr 22 '16 at 8:30











                                                              • @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                                – Dreamspace President
                                                                Apr 22 '16 at 12:45











                                                              • @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:26











                                                              • @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:34











                                                              • @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                                – Dreamspace President
                                                                May 4 '16 at 12:45
















                                                              0












                                                              0








                                                              0







                                                              EDIT: Instead of using this WatchService approach, a simple 1 second timer thread could be used to check if the indicatorFile.exists(). Delete it, then bring the application toFront().



                                                              EDIT: I would like to know why this was downvoted. It's the best solution I have seen so far. E.g. the server socket approach fails if another application happens to already be listening to the port.



                                                              Just download Microsoft Windows Sysinternals TCPView (or use netstat), start it, sort by "State", look for the line block that says "LISTENING", pick one whose remote address says your computer's name, put that port into your new-Socket()-solution. In my implementation of it, I can produce failure every time. And it's logical, because it's the very foundation of the approach. Or what am I not getting regarding how to implement this?



                                                              Please inform me if and how I am wrong about this!



                                                              My view - which I am asking you to disprove if possible - is that developers are being advised to use an approach in production code that will fail in at least 1 of about 60000 cases. And if this view happens to be correct, then it can absolutely not be that a solution presented that does not have this problem is downvoted and criticized for its amount of code.



                                                              Disadvantages of the socket approach in comparison:




                                                              • Fails if the wrong lottery ticket (port number) is chosen.

                                                              • Fails in multi user environment: Only one user can run the application at the same time. (My approach would have to be slightly changed to create the file(s) in the user tree, but that's trivial.)

                                                              • Fails if firewall rules are too strict.

                                                              • Makes suspicious users (which I did meet in the wild) wonder what shenanigans you're up to when your text editor is claiming a server socket.




                                                              I just had a nice idea for how to solve the new-instance-to-existing-instance Java communication problem in a way that should work on every system. So, I whipped up this class in about two hours. Works like a charm :D



                                                              It's based on Robert's file lock approach (also on this page), which I have used ever since. To tell the already running instance that another instance tried to start (but didn't) ... a file is created and immediately deleted, and the first instance uses the WatchService to detect this folder content change. I can't believe that apparently this is a new idea, given how fundamental the problem is.



                                                              This can easily be changed to just create and not delete the file, and then information can be put into it that the proper instance can evaluate, e.g. the command line arguments - and the proper instance can then perform the deletion. Personally, I only needed to know when to restore my application's window and send it to front.



                                                              Example use:



                                                              public static void main(final String args) {

                                                              // ENSURE SINGLE INSTANCE
                                                              if (!SingleInstanceChecker.INSTANCE.isOnlyInstance(Main::otherInstanceTriedToLaunch, false)) {
                                                              System.exit(0);
                                                              }

                                                              // launch rest of application here
                                                              System.out.println("Application starts properly because it's the only instance.");
                                                              }

                                                              private static void otherInstanceTriedToLaunch() {
                                                              // Restore your application window and bring it to front.
                                                              // But make sure your situation is apt: This method could be called at *any* time.
                                                              System.err.println("Deiconified because other instance tried to start.");
                                                              }


                                                              Here's the class:



                                                              package yourpackagehere;

                                                              import javax.swing.*;
                                                              import java.io.File;
                                                              import java.io.IOException;
                                                              import java.io.RandomAccessFile;
                                                              import java.nio.channels.FileLock;
                                                              import java.nio.file.*;




                                                              /**
                                                              * SingleInstanceChecker v[(2), 2016-04-22 08:00 UTC] by dreamspace-president.com
                                                              * <p>
                                                              * (file lock single instance solution by Robert https://stackoverflow.com/a/2002948/3500521)
                                                              */
                                                              public enum SingleInstanceChecker {

                                                              INSTANCE; // HAHA! The CONFUSION!


                                                              final public static int POLLINTERVAL = 1000;
                                                              final public static File LOCKFILE = new File("SINGLE_INSTANCE_LOCKFILE");
                                                              final public static File DETECTFILE = new File("EXTRA_INSTANCE_DETECTFILE");


                                                              private boolean hasBeenUsedAlready = false;


                                                              private WatchService watchService = null;
                                                              private RandomAccessFile randomAccessFileForLock = null;
                                                              private FileLock fileLock = null;


                                                              /**
                                                              * CAN ONLY BE CALLED ONCE.
                                                              * <p>
                                                              * Assumes that the program will close if FALSE is returned: The other-instance-tries-to-launch listener is not
                                                              * installed in that case.
                                                              * <p>
                                                              * Checks if another instance is already running (temp file lock / shutdownhook). Depending on the accessibility of
                                                              * the temp file the return value will be true or false. This approach even works even if the virtual machine
                                                              * process gets killed. On the next run, the program can even detect if it has shut down irregularly, because then
                                                              * the file will still exist. (Thanks to Robert https://stackoverflow.com/a/2002948/3500521 for that solution!)
                                                              * <p>
                                                              * Additionally, the method checks if another instance tries to start. In a crappy way, because as awesome as Java
                                                              * is, it lacks some fundamental features. Don't worry, it has only been 25 years, it'll sure come eventually.
                                                              *
                                                              * @param codeToRunIfOtherInstanceTriesToStart Can be null. If not null and another instance tries to start (which
                                                              * changes the detect-file), the code will be executed. Could be used to
                                                              * bring the current (=old=only) instance to front. If null, then the
                                                              * watcher will not be installed at all, nor will the trigger file be
                                                              * created. (Null means that you just don't want to make use of this
                                                              * half of the class' purpose, but then you would be better advised to
                                                              * just use the 24 line method by Robert.)
                                                              * <p>
                                                              * BE CAREFUL with the code: It will potentially be called until the
                                                              * very last moment of the program's existence, so if you e.g. have a
                                                              * shutdown procedure or a window that would be brought to front, check
                                                              * if the procedure has not been triggered yet or if the window still
                                                              * exists / hasn't been disposed of yet. Or edit this class to be more
                                                              * comfortable. This would e.g. allow you to remove some crappy
                                                              * comments. Attribution would be nice, though.
                                                              * @param executeOnAWTEventDispatchThread Convenience function. If false, the code will just be executed. If
                                                              * true, it will be detected if we're currently on that thread. If so,
                                                              * the code will just be executed. If not so, the code will be run via
                                                              * SwingUtilities.invokeLater().
                                                              * @return if this is the only instance
                                                              */
                                                              public boolean isOnlyInstance(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              if (hasBeenUsedAlready) {
                                                              throw new IllegalStateException("This class/method can only be used once, which kinda makes sense if you think about it.");
                                                              }
                                                              hasBeenUsedAlready = true;

                                                              final boolean ret = canLockFileBeCreatedAndLocked();

                                                              if (codeToRunIfOtherInstanceTriesToStart != null) {
                                                              if (ret) {
                                                              // Only if this is the only instance, it makes sense to install a watcher for additional instances.
                                                              installOtherInstanceLaunchAttemptWatcher(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread);
                                                              } else {
                                                              // Only if this is NOT the only instance, it makes sense to create&delete the trigger file that will effect notification of the other instance.
                                                              //
                                                              // Regarding "codeToRunIfOtherInstanceTriesToStart != null":
                                                              // While creation/deletion of the file concerns THE OTHER instance of the program,
                                                              // making it dependent on the call made in THIS instance makes sense
                                                              // because the code executed is probably the same.
                                                              createAndDeleteOtherInstanceWatcherTriggerFile();
                                                              }
                                                              }

                                                              optionallyInstallShutdownHookThatCleansEverythingUp();

                                                              return ret;
                                                              }


                                                              private void createAndDeleteOtherInstanceWatcherTriggerFile() {

                                                              try {
                                                              final RandomAccessFile randomAccessFileForDetection = new RandomAccessFile(DETECTFILE, "rw");
                                                              randomAccessFileForDetection.close();
                                                              Files.deleteIfExists(DETECTFILE.toPath()); // File is created and then instantly deleted. Not a problem for the WatchService :)
                                                              } catch (Exception e) {
                                                              e.printStackTrace();
                                                              }
                                                              }


                                                              private boolean canLockFileBeCreatedAndLocked() {

                                                              try {
                                                              randomAccessFileForLock = new RandomAccessFile(LOCKFILE, "rw");
                                                              fileLock = randomAccessFileForLock.getChannel().tryLock();
                                                              return fileLock != null;
                                                              } catch (Exception e) {
                                                              return false;
                                                              }
                                                              }


                                                              private void installOtherInstanceLaunchAttemptWatcher(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              // PREPARE WATCHSERVICE AND STUFF
                                                              try {
                                                              watchService = FileSystems.getDefault().newWatchService();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }
                                                              final File appFolder = new File("").getAbsoluteFile(); // points to current folder
                                                              final Path appFolderWatchable = appFolder.toPath();


                                                              // REGISTER CURRENT FOLDER FOR WATCHING FOR FILE DELETIONS
                                                              try {
                                                              appFolderWatchable.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }


                                                              // INSTALL WATCHER THAT LOOKS IF OUR detectFile SHOWS UP IN THE DIRECTORY CHANGES. IF THERE'S A CHANGE, ANOTHER INSTANCE TRIED TO START, SO NOTIFY THE CURRENT ONE OF THAT.
                                                              final Thread t = new Thread(() -> watchForDirectoryChangesOnExtraThread(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread));
                                                              t.setDaemon(true);
                                                              t.setName("directory content change watcher");
                                                              t.start();
                                                              }


                                                              private void optionallyInstallShutdownHookThatCleansEverythingUp() {

                                                              if (fileLock == null && randomAccessFileForLock == null && watchService == null) {
                                                              return;
                                                              }

                                                              final Thread shutdownHookThread = new Thread(() -> {
                                                              try {
                                                              if (fileLock != null) {
                                                              fileLock.release();
                                                              }
                                                              if (randomAccessFileForLock != null) {
                                                              randomAccessFileForLock.close();
                                                              }
                                                              Files.deleteIfExists(LOCKFILE.toPath());
                                                              } catch (Exception ignore) {
                                                              }
                                                              if (watchService != null) {
                                                              try {
                                                              watchService.close();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              }
                                                              }
                                                              });
                                                              Runtime.getRuntime().addShutdownHook(shutdownHookThread);
                                                              }


                                                              private void watchForDirectoryChangesOnExtraThread(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              while (true) { // To eternity and beyond! Until the universe shuts down. (Should be a volatile boolean, but this class only has absolutely required features.)

                                                              try {
                                                              Thread.sleep(POLLINTERVAL);
                                                              } catch (InterruptedException e) {
                                                              e.printStackTrace();
                                                              }


                                                              final WatchKey wk;
                                                              try {
                                                              wk = watchService.poll();
                                                              } catch (ClosedWatchServiceException e) {
                                                              // This situation would be normal if the watcher has been closed, but our application never does that.
                                                              e.printStackTrace();
                                                              return;
                                                              }

                                                              if (wk == null || !wk.isValid()) {
                                                              continue;
                                                              }


                                                              for (WatchEvent<?> we : wk.pollEvents()) {

                                                              final WatchEvent.Kind<?> kind = we.kind();
                                                              if (kind == StandardWatchEventKinds.OVERFLOW) {
                                                              System.err.println("OVERFLOW of directory change events!");
                                                              continue;
                                                              }


                                                              final WatchEvent<Path> watchEvent = (WatchEvent<Path>) we;
                                                              final File file = watchEvent.context().toFile();


                                                              if (file.equals(DETECTFILE)) {

                                                              if (!executeOnAWTEventDispatchThread || SwingUtilities.isEventDispatchThread()) {
                                                              codeToRunIfOtherInstanceTriesToStart.run();
                                                              } else {
                                                              SwingUtilities.invokeLater(codeToRunIfOtherInstanceTriesToStart);
                                                              }

                                                              break;

                                                              } else {
                                                              System.err.println("THIS IS THE FILE THAT WAS DELETED: " + file);
                                                              }

                                                              }

                                                              wk.reset();
                                                              }
                                                              }

                                                              }





                                                              share|improve this answer















                                                              EDIT: Instead of using this WatchService approach, a simple 1 second timer thread could be used to check if the indicatorFile.exists(). Delete it, then bring the application toFront().



                                                              EDIT: I would like to know why this was downvoted. It's the best solution I have seen so far. E.g. the server socket approach fails if another application happens to already be listening to the port.



                                                              Just download Microsoft Windows Sysinternals TCPView (or use netstat), start it, sort by "State", look for the line block that says "LISTENING", pick one whose remote address says your computer's name, put that port into your new-Socket()-solution. In my implementation of it, I can produce failure every time. And it's logical, because it's the very foundation of the approach. Or what am I not getting regarding how to implement this?



                                                              Please inform me if and how I am wrong about this!



                                                              My view - which I am asking you to disprove if possible - is that developers are being advised to use an approach in production code that will fail in at least 1 of about 60000 cases. And if this view happens to be correct, then it can absolutely not be that a solution presented that does not have this problem is downvoted and criticized for its amount of code.



                                                              Disadvantages of the socket approach in comparison:




                                                              • Fails if the wrong lottery ticket (port number) is chosen.

                                                              • Fails in multi user environment: Only one user can run the application at the same time. (My approach would have to be slightly changed to create the file(s) in the user tree, but that's trivial.)

                                                              • Fails if firewall rules are too strict.

                                                              • Makes suspicious users (which I did meet in the wild) wonder what shenanigans you're up to when your text editor is claiming a server socket.




                                                              I just had a nice idea for how to solve the new-instance-to-existing-instance Java communication problem in a way that should work on every system. So, I whipped up this class in about two hours. Works like a charm :D



                                                              It's based on Robert's file lock approach (also on this page), which I have used ever since. To tell the already running instance that another instance tried to start (but didn't) ... a file is created and immediately deleted, and the first instance uses the WatchService to detect this folder content change. I can't believe that apparently this is a new idea, given how fundamental the problem is.



                                                              This can easily be changed to just create and not delete the file, and then information can be put into it that the proper instance can evaluate, e.g. the command line arguments - and the proper instance can then perform the deletion. Personally, I only needed to know when to restore my application's window and send it to front.



                                                              Example use:



                                                              public static void main(final String args) {

                                                              // ENSURE SINGLE INSTANCE
                                                              if (!SingleInstanceChecker.INSTANCE.isOnlyInstance(Main::otherInstanceTriedToLaunch, false)) {
                                                              System.exit(0);
                                                              }

                                                              // launch rest of application here
                                                              System.out.println("Application starts properly because it's the only instance.");
                                                              }

                                                              private static void otherInstanceTriedToLaunch() {
                                                              // Restore your application window and bring it to front.
                                                              // But make sure your situation is apt: This method could be called at *any* time.
                                                              System.err.println("Deiconified because other instance tried to start.");
                                                              }


                                                              Here's the class:



                                                              package yourpackagehere;

                                                              import javax.swing.*;
                                                              import java.io.File;
                                                              import java.io.IOException;
                                                              import java.io.RandomAccessFile;
                                                              import java.nio.channels.FileLock;
                                                              import java.nio.file.*;




                                                              /**
                                                              * SingleInstanceChecker v[(2), 2016-04-22 08:00 UTC] by dreamspace-president.com
                                                              * <p>
                                                              * (file lock single instance solution by Robert https://stackoverflow.com/a/2002948/3500521)
                                                              */
                                                              public enum SingleInstanceChecker {

                                                              INSTANCE; // HAHA! The CONFUSION!


                                                              final public static int POLLINTERVAL = 1000;
                                                              final public static File LOCKFILE = new File("SINGLE_INSTANCE_LOCKFILE");
                                                              final public static File DETECTFILE = new File("EXTRA_INSTANCE_DETECTFILE");


                                                              private boolean hasBeenUsedAlready = false;


                                                              private WatchService watchService = null;
                                                              private RandomAccessFile randomAccessFileForLock = null;
                                                              private FileLock fileLock = null;


                                                              /**
                                                              * CAN ONLY BE CALLED ONCE.
                                                              * <p>
                                                              * Assumes that the program will close if FALSE is returned: The other-instance-tries-to-launch listener is not
                                                              * installed in that case.
                                                              * <p>
                                                              * Checks if another instance is already running (temp file lock / shutdownhook). Depending on the accessibility of
                                                              * the temp file the return value will be true or false. This approach even works even if the virtual machine
                                                              * process gets killed. On the next run, the program can even detect if it has shut down irregularly, because then
                                                              * the file will still exist. (Thanks to Robert https://stackoverflow.com/a/2002948/3500521 for that solution!)
                                                              * <p>
                                                              * Additionally, the method checks if another instance tries to start. In a crappy way, because as awesome as Java
                                                              * is, it lacks some fundamental features. Don't worry, it has only been 25 years, it'll sure come eventually.
                                                              *
                                                              * @param codeToRunIfOtherInstanceTriesToStart Can be null. If not null and another instance tries to start (which
                                                              * changes the detect-file), the code will be executed. Could be used to
                                                              * bring the current (=old=only) instance to front. If null, then the
                                                              * watcher will not be installed at all, nor will the trigger file be
                                                              * created. (Null means that you just don't want to make use of this
                                                              * half of the class' purpose, but then you would be better advised to
                                                              * just use the 24 line method by Robert.)
                                                              * <p>
                                                              * BE CAREFUL with the code: It will potentially be called until the
                                                              * very last moment of the program's existence, so if you e.g. have a
                                                              * shutdown procedure or a window that would be brought to front, check
                                                              * if the procedure has not been triggered yet or if the window still
                                                              * exists / hasn't been disposed of yet. Or edit this class to be more
                                                              * comfortable. This would e.g. allow you to remove some crappy
                                                              * comments. Attribution would be nice, though.
                                                              * @param executeOnAWTEventDispatchThread Convenience function. If false, the code will just be executed. If
                                                              * true, it will be detected if we're currently on that thread. If so,
                                                              * the code will just be executed. If not so, the code will be run via
                                                              * SwingUtilities.invokeLater().
                                                              * @return if this is the only instance
                                                              */
                                                              public boolean isOnlyInstance(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              if (hasBeenUsedAlready) {
                                                              throw new IllegalStateException("This class/method can only be used once, which kinda makes sense if you think about it.");
                                                              }
                                                              hasBeenUsedAlready = true;

                                                              final boolean ret = canLockFileBeCreatedAndLocked();

                                                              if (codeToRunIfOtherInstanceTriesToStart != null) {
                                                              if (ret) {
                                                              // Only if this is the only instance, it makes sense to install a watcher for additional instances.
                                                              installOtherInstanceLaunchAttemptWatcher(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread);
                                                              } else {
                                                              // Only if this is NOT the only instance, it makes sense to create&delete the trigger file that will effect notification of the other instance.
                                                              //
                                                              // Regarding "codeToRunIfOtherInstanceTriesToStart != null":
                                                              // While creation/deletion of the file concerns THE OTHER instance of the program,
                                                              // making it dependent on the call made in THIS instance makes sense
                                                              // because the code executed is probably the same.
                                                              createAndDeleteOtherInstanceWatcherTriggerFile();
                                                              }
                                                              }

                                                              optionallyInstallShutdownHookThatCleansEverythingUp();

                                                              return ret;
                                                              }


                                                              private void createAndDeleteOtherInstanceWatcherTriggerFile() {

                                                              try {
                                                              final RandomAccessFile randomAccessFileForDetection = new RandomAccessFile(DETECTFILE, "rw");
                                                              randomAccessFileForDetection.close();
                                                              Files.deleteIfExists(DETECTFILE.toPath()); // File is created and then instantly deleted. Not a problem for the WatchService :)
                                                              } catch (Exception e) {
                                                              e.printStackTrace();
                                                              }
                                                              }


                                                              private boolean canLockFileBeCreatedAndLocked() {

                                                              try {
                                                              randomAccessFileForLock = new RandomAccessFile(LOCKFILE, "rw");
                                                              fileLock = randomAccessFileForLock.getChannel().tryLock();
                                                              return fileLock != null;
                                                              } catch (Exception e) {
                                                              return false;
                                                              }
                                                              }


                                                              private void installOtherInstanceLaunchAttemptWatcher(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              // PREPARE WATCHSERVICE AND STUFF
                                                              try {
                                                              watchService = FileSystems.getDefault().newWatchService();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }
                                                              final File appFolder = new File("").getAbsoluteFile(); // points to current folder
                                                              final Path appFolderWatchable = appFolder.toPath();


                                                              // REGISTER CURRENT FOLDER FOR WATCHING FOR FILE DELETIONS
                                                              try {
                                                              appFolderWatchable.register(watchService, StandardWatchEventKinds.ENTRY_DELETE);
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              return;
                                                              }


                                                              // INSTALL WATCHER THAT LOOKS IF OUR detectFile SHOWS UP IN THE DIRECTORY CHANGES. IF THERE'S A CHANGE, ANOTHER INSTANCE TRIED TO START, SO NOTIFY THE CURRENT ONE OF THAT.
                                                              final Thread t = new Thread(() -> watchForDirectoryChangesOnExtraThread(codeToRunIfOtherInstanceTriesToStart, executeOnAWTEventDispatchThread));
                                                              t.setDaemon(true);
                                                              t.setName("directory content change watcher");
                                                              t.start();
                                                              }


                                                              private void optionallyInstallShutdownHookThatCleansEverythingUp() {

                                                              if (fileLock == null && randomAccessFileForLock == null && watchService == null) {
                                                              return;
                                                              }

                                                              final Thread shutdownHookThread = new Thread(() -> {
                                                              try {
                                                              if (fileLock != null) {
                                                              fileLock.release();
                                                              }
                                                              if (randomAccessFileForLock != null) {
                                                              randomAccessFileForLock.close();
                                                              }
                                                              Files.deleteIfExists(LOCKFILE.toPath());
                                                              } catch (Exception ignore) {
                                                              }
                                                              if (watchService != null) {
                                                              try {
                                                              watchService.close();
                                                              } catch (IOException e) {
                                                              e.printStackTrace();
                                                              }
                                                              }
                                                              });
                                                              Runtime.getRuntime().addShutdownHook(shutdownHookThread);
                                                              }


                                                              private void watchForDirectoryChangesOnExtraThread(final Runnable codeToRunIfOtherInstanceTriesToStart, final boolean executeOnAWTEventDispatchThread) {

                                                              while (true) { // To eternity and beyond! Until the universe shuts down. (Should be a volatile boolean, but this class only has absolutely required features.)

                                                              try {
                                                              Thread.sleep(POLLINTERVAL);
                                                              } catch (InterruptedException e) {
                                                              e.printStackTrace();
                                                              }


                                                              final WatchKey wk;
                                                              try {
                                                              wk = watchService.poll();
                                                              } catch (ClosedWatchServiceException e) {
                                                              // This situation would be normal if the watcher has been closed, but our application never does that.
                                                              e.printStackTrace();
                                                              return;
                                                              }

                                                              if (wk == null || !wk.isValid()) {
                                                              continue;
                                                              }


                                                              for (WatchEvent<?> we : wk.pollEvents()) {

                                                              final WatchEvent.Kind<?> kind = we.kind();
                                                              if (kind == StandardWatchEventKinds.OVERFLOW) {
                                                              System.err.println("OVERFLOW of directory change events!");
                                                              continue;
                                                              }


                                                              final WatchEvent<Path> watchEvent = (WatchEvent<Path>) we;
                                                              final File file = watchEvent.context().toFile();


                                                              if (file.equals(DETECTFILE)) {

                                                              if (!executeOnAWTEventDispatchThread || SwingUtilities.isEventDispatchThread()) {
                                                              codeToRunIfOtherInstanceTriesToStart.run();
                                                              } else {
                                                              SwingUtilities.invokeLater(codeToRunIfOtherInstanceTriesToStart);
                                                              }

                                                              break;

                                                              } else {
                                                              System.err.println("THIS IS THE FILE THAT WAS DELETED: " + file);
                                                              }

                                                              }

                                                              wk.reset();
                                                              }
                                                              }

                                                              }






                                                              share|improve this answer














                                                              share|improve this answer



                                                              share|improve this answer








                                                              edited Mar 5 '18 at 13:14

























                                                              answered Apr 21 '16 at 14:19









                                                              Dreamspace PresidentDreamspace President

                                                              653726




                                                              653726













                                                              • You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                                – user207421
                                                                Apr 22 '16 at 8:30











                                                              • @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                                – Dreamspace President
                                                                Apr 22 '16 at 12:45











                                                              • @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:26











                                                              • @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:34











                                                              • @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                                – Dreamspace President
                                                                May 4 '16 at 12:45





















                                                              • You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                                – user207421
                                                                Apr 22 '16 at 8:30











                                                              • @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                                – Dreamspace President
                                                                Apr 22 '16 at 12:45











                                                              • @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:26











                                                              • @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                                – Dreamspace President
                                                                Apr 26 '16 at 9:34











                                                              • @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                                – Dreamspace President
                                                                May 4 '16 at 12:45



















                                                              You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                              – user207421
                                                              Apr 22 '16 at 8:30





                                                              You do not need hundreds of lines of code to solve this problem. new ServerSocket() with a catch block is quite adequate,

                                                              – user207421
                                                              Apr 22 '16 at 8:30













                                                              @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                              – Dreamspace President
                                                              Apr 22 '16 at 12:45





                                                              @EJP Are you referring to the accepted answer, or what are you talking about? I have searched quite a bit for an x-platform no-extra-library solution that doesn't fail e.g. because some socket happened to already be occupied by a different application. If there is a solution to this - especially as super simple as you are referring to - then I would like to know about it.

                                                              – Dreamspace President
                                                              Apr 22 '16 at 12:45













                                                              @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                              – Dreamspace President
                                                              Apr 26 '16 at 9:26





                                                              @EJP: I want to ask again 1) what trivial solution you are referring to that you have been dangling like a carrot in front of my head, 2) in case it's the socket solution the accepted answer begins with, if one or more of my "Disadvantages of the socket approach" bullet points apply, and 3) if so, why in spite of those shortcomings you would still recommend that approach over one like mine.

                                                              – Dreamspace President
                                                              Apr 26 '16 at 9:26













                                                              @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                              – Dreamspace President
                                                              Apr 26 '16 at 9:34





                                                              @EJP: The problem is that your voice has quite some weight, as you're sure aware, but all evidence that I have forces me to be convinced that your advice here is wrong. See, I'm not insisting that my solution is right and all that, but I am an evidence-based machine. Don't you see that your position gives you a responsibility to the community to fill in the missing puzzle pieces of this communication that you started?

                                                              – Dreamspace President
                                                              Apr 26 '16 at 9:34













                                                              @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                              – Dreamspace President
                                                              May 4 '16 at 12:45







                                                              @EJP: Since there has sadly been no reaction from you, here's what I will assume as fact: The truth about the server socket solution is that it really is deeply flawed, and the reason for most who chose it might have been "The others use this, too.", or they might have been deceived into using it by irresponsible people. I guess that part of the reason why you didn't dignify us with the required explanations is that you can't fathom that/why you never questioned this approach, and you don't want to make a public statement revealing this.

                                                              – Dreamspace President
                                                              May 4 '16 at 12:45







                                                              protected by Community Feb 4 '16 at 16:43



                                                              Thank you for your interest in this question.
                                                              Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                                                              Would you like to answer one of these unanswered questions instead?



                                                              Popular posts from this blog

                                                              Angular Downloading a file using contenturl with Basic Authentication

                                                              Monofisismo

                                                              Olmecas