1 2 Previous Next 22 Replies Latest reply on Nov 4, 2010 5:57 AM by EJP

    Ensure single instance of Java application

    807580
      Hi,

      I'd like to make sure that only one instance of my Java application can be run and I've done some search around. The recommended approach seems to be using ServerSocket that occupies a certain port.

      On the other hand I've seen that JConsole could display the names of all Java processes that are running. This is perhaps another approach to the issue? JConsole is said to be a pure Java tool, so I was wondering how this is implemented. I've googled a bit but still could not find out how. Could someone please give me a hint?

      Thanks a lot!
        • 1. Re: Ensure single instance of Java application
          gimbal2
          You could take a look at the source code. This forum thread seems to indicate where to find it:

          [http://forums.sun.com/thread.jspa?threadID=788974|http://forums.sun.com/thread.jspa?threadID=788974]
          • 2. Re: Ensure single instance of Java application
            807580
            SwordDevil wrote:
            Hi,

            I'd like to make sure that only one instance of my Java application can be run and I've done some search around. The recommended approach seems to be using ServerSocket that occupies a certain port.

            On the other hand I've seen that JConsole could display the names of all Java processes that are running. This is perhaps another approach to the issue? JConsole is said to be a pure Java tool.
            Not especially. How it finds local Java processes is primarily platform-specific, and messy. Or it uses JMX, if it can. That's a possibility, but I'm not seeing a clear advantage over the simple server socket approach.
            • 3. Re: Ensure single instance of Java application
              807580
              Use some kind of locking mechanism. This method uses a simple lock on a file and cleans up behind itself reliably and works across all platforms...
              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;
              }
              Or if you can think of another locking mechanism through DB interaction, that would be equally effective as well.
              • 4. Re: Ensure single instance of Java application
                807580
                kilyas wrote:
                Use some kind of locking mechanism. This method uses a simple lock on a file and cleans up behind itself reliably
                Not in the case of a power cut.
                • 5. Re: Ensure single instance of Java application
                  807580
                  Using a ServerSocket is basically a one liner. It is the simplest approach IMHO.
                  • 6. Re: Ensure single instance of Java application
                    807580
                    Does this lock mechanism work when e.g. the user kills the app using Task Manager? I've never tested this myself although some discussions say it may fail.
                    • 7. Re: Ensure single instance of Java application
                      masijade
                      SwordDevil wrote:
                      Does this lock mechanism work when e.g. the user kills the app using Task Manager? I've never tested this myself although some discussions say it may fail.
                      So what, in your mind, is wrong with the ServerSocket approach? Why do all "newbies" immediately discard this approach and then go out and try all these other complex, unreliable, obscure, and/or otherwise questionable practices?
                      • 8. Re: Ensure single instance of Java application
                        807580
                        ServerSocket seems to be a reliable approach, and it's simple, and I like it. I'm just curious how JConsole detects all running Java processes.
                        • 9. Re: Ensure single instance of Java application
                          807580
                          SwordDevil wrote:
                          ServerSocket seems to be a reliable approach, and it's simple, and I like it. I'm just curious how JConsole detects all running Java processes.
                          I think one has to be careful in that "pure Java" != "platform independence" even though at first glance you might think otherwise. Some code could be "pure Java" in that it doesn't actually call any native code (directly) but it could still be platform dependent in doing things like for example examining process lists on an OS. Of course that code could also detect which OS and do the "right thing" for such activity based on that information but it's not completely platform independent in the "run anywhere" philosophy.
                          • 10. Re: Ensure single instance of Java application
                            807580
                            SwordDevil wrote:
                            ServerSocket seems to be a reliable approach, and it's simple, and I like it. I'm just curious how JConsole detects all running Java processes.
                            It varies from platform to platform.
                            • 11. Re: Ensure single instance of Java application
                              793415
                              SwordDevil wrote:
                              ..I'd like to make sure that only one instance of my Java application can be run ..
                              Does the app. have a GUI? Can you distribute it from a server or the web?

                              If yes to both, launch it using JWS and use the SingleInstanceService to ensure the goal. Here is a small [demo. of the SingleInstanceService|http://pscode.org/jws/api.html#sis].
                              • 12. Re: Ensure single instance of Java application
                                ow003765
                                masijade wrote:
                                So what, in your mind, is wrong with the ServerSocket approach? Why do all "newbies" immediately discard this approach and then go out and try all these other complex, unreliable, obscure, and/or otherwise questionable practices?
                                Found this thread via Google on the original Sun forums. Searching here on the exact title didn't find it!

                                Anyway, I'm using the ServerSocket approach:
                                try
                                   {
                                   InetAddress localAddress = InetAddress.getLocalHost();
                                   log.info("InetAddress.getLocalHost(): " + localAddress);
                                   socket = new ServerSocket(12345, 1, localAddress);
                                   } // end try
                                catch (Exception e)
                                   {
                                   throw new Exception("Program already running, exiting");
                                   } // end catch
                                Unfortunately, this is not working reliably. It works some of the time; I can see in the logs the "Program already running" message. But then from time to time I'll see 4 instances running at the same time, and they are each trying to do actual work, not just hung in some exit state.

                                The runtime platform is Linux 2.6.9-34.ELsmp x86_64, via cron; I think it is running some version of Redhat, old obviously. Java version is 1.6.0_16, 64-bit.

                                The job runs every 15 minutes. Any ideas why this is not working all the time?

                                Thanks.

                                Edited by: ow003765 on Nov 3, 2010 4:01 PM
                                • 13. Re: Ensure single instance of Java application
                                  796440
                                  Either getLocalHost() is returning different InetAddresses, or each previous instance has closed its socket by the time the next one starts.
                                  • 14. Re: Ensure single instance of Java application
                                    EJP
                                    Get rid of the local address and use null instead. And make sure that 'socket' is a class member that is going to persist for the life of the application: if it gets GCs it will be closed.
                                    1 2 Previous Next