To stop running another instance of my java program

Hi,

I have made a java application. Its not web based, Its not Desktop Application. Its command application.

 I donot wanted that my program can have another instance running, if it is already running.

How can I do this.

I have created very simple application to test.

Please help me, so that I cannot run another instance of this.

Thanks for your co-operation
import java.util.Timer;
import java.util.TimerTask;
 
public class TimerTest {
 
	public static
	void main(String[] args)
	throws Exception
	{
		int initialDelay = 5000;
	    int interval = 1000;
 
		Timer timer = new Timer();
		timer.schedule(new TimerTask()
		{
		    public void run()
		    {
		        System.out.println("I am running");
		    }
 
		}, initialDelay, interval);
	}
}

Open in new window

tia_kamakshiAsked:
Who is Participating?
 
sciuriwareConnect With a Mentor Commented:
Probably this solution is overkill, but it provides several functions:

import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.io.File;
import java.io.RandomAccessFile;

/* Provides instance or group solitarity (=only one instance allowed at a time).
 * The implementation is platform independent since MSWindows98, LINUX-2 and
 * UNIX SVR4, and can be deployed as an inter-process synchonisation tool.
 *
 * @author     J.F.Lanting
 * @since      07-Oct-2002
 */

/*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*/
/*    APPLICATION SOLITARITY:                                                */
/*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*/

public class Solitarity
{
static String programName; // Fill in yourself .....

static String userName = System.getProperty("user.name");

   /**
    * Lock to be applied on the solitarity file.
    */
   private static FileLock solitarityLock = null;

   /**
    * Channel of the solitatity file to lead locking.
    */
   private static FileChannel solitarityChannel = null;

   /**
    * Token file which locking signals solitarity.
    */
   private static RandomAccessFile solitarityFile;

   private static String getTempDirectory()
   {
      return(System.getProperty("java.io.tmpdir") + '/');
   }


   /**
    * Sets / tests for a mutual application instance lock on a temporary lockfile.
    * <p>
    * Can be used to guarantee that only one instance of this application is running.<BR>
    * Returns <b>null</b> IF this is the only running application defined by the given token,<BR>
    * otherwise the name (only) of the other user who blocks you.<BR>
    * The lock must be removed by <b>Sy.unSolitaire()</b>
    * if the application must continue to run simultaneously with others.<BR>
    * The lock is effectively removed anyway when the application exits or crashes.<BR>
    * <b>NOTE:</b> the lockfile is NOT deleted on exit as it might be locked by an other process by then!
    * </p>
    *
    * @return null if you are the only instance, otherwise the name of the other user.
    */
   public static String solitaire()
   {
   String result = solitaire(programName);
   int index;

      if(result != null && (index = result.indexOf(" ")) > 0)
      {
         result = result.substring(0, index); // User name only!
      }
      return(result);
   }


   /**
    * Sets / tests for a mutual application instance lock on a temporary lockfile.
    * <p>
    * Can be used to guarantee that only one member of an application group is running.<BR>
    * Returns null IF this is the only running application defined by the given token,<BR>
    * otherwise the name and the program of the other user who blocks you.<BR>
    * The lock must be removed by <b>Sy.unSolitaire()</b>
    * if the application must continue to run simultaneously with others.<BR>
    * The lock is effectively removed anyway when the application exits or crashes.<BR>
    * <b>NOTE:</b> the lockfile is NOT deleted on exit as it might be locked by an other process by then!
    * </p>
    *
    * @param token identification for the group the be solitair in.
    * @return null if you are alone or the other user if not.
    */
   public static String solitaire(String token)
   {
   String mark;                        // Readable mark in the lock file.
   File solitarityLockFile;            // To detect existence only.
   boolean myLockFile;                 // If there was no lock file..

      if(solitarityLock != null)
      {
         return(null);        // Having a lock myself : already secured it.
      }

// The first 8 bytes of "mark" are the lock area.

      mark = "LOCK BY " + userName + " running \"" + programName + "\"\n";
      solitarityLockFile = new File(getTempDirectory() + ".solitaire_" + token);
      myLockFile = !solitarityLockFile.exists();

      try
      {
         solitarityFile = new RandomAccessFile(solitarityLockFile, "rws");
         solitarityChannel = solitarityFile.getChannel();
         if(myLockFile)
         {
            solitarityFile.writeBytes(mark); // Write NOW!
         }
         if((solitarityLock = solitarityChannel.tryLock(0, 8, false)) == null)
         {
            solitarityFile.seek(8);
            return(solitarityFile.readLine());
         }
         if(!myLockFile)               // But locked by me, so mark it.
         {
            solitarityFile.writeBytes(mark); // Write (delayed).
         }
      }
      catch(Exception e)
      {
         return("somebody(!?)");       // No access? or not alone!
      }
      return(null);
   }


   /**
    * Releases an application lock set by <b>Sy.solitaire()</b>.
    * <p>
    * This methods gives way to other applications, although any lock of this kind<BR>
    * is automatically removed at exit or when the application crashes.
    * </p>
    */
   public static void unSolitaire()
   {
      try
      {
         if(solitarityLock != null)
         {
            solitarityLock.release();
            solitarityLock = null;
            solitarityChannel = null;
         }

         if(solitarityFile != null)
         {
            solitarityFile.close();
            solitarityFile = null;
         }
      }
      catch(Exception e)
      {
         System.out.println(":\n:: FAILED TO UNLOCK SOLITARITY LOCKFILE");
      }
   }
}

;JOOP!
0
 
sciuriwareCommented:
You should either use a lock-file or a socket which can only be opened by 1 instance.

The lockfile solution is platform independent.

;JOOP!
0
 
Thomas4019Commented:
You could create a File when you start your program. Then use File.exists() to check whether your java program should terminate on startup. Then use File.deleteOnExit() to tell the Java JRE to delete the file on exit.
static File marker = new File("C:/running.txt");
 
public static void main(String args[])
{
   if(marker.exists())
      System.exit(0);
   
   marker.create();
   marker.deleteOnExit();
 
   //ONLY ONE INSTANCE IS NOW RUNNING
   //YOUR CODE HERE
}

Open in new window

0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
tia_kamakshiAuthor Commented:
Hi,

Thanks for your reply.

I am not sure that how strong this logic will be for my application. If for some reason my program crashes and file is not deleted on exit.

And on exit of program, java donot unlock the file, then it will be problem to restart application.

And If ask user to delete file from particular directory, if application doesn't start. I don't know what user will think of my program logic.

How about singleton pattern,  Isn't it singleton pattern will help me. If it is fine.

If it is fine, then can you please help me applying singlton pattern to my program.

I need your suggestions and help

Many Thanks
0
 
sciuriwareCommented:
On exit or crash all locks are wiped out.
It is not important if the file remains there or is deleted.
I have applied this construct for 10 years in all kinds of environments
without any flaw.
That means, also on UNIX and solaris.

;JOOP!
0
 
sciuriwareCommented:
A singleton will not help you as it is unknown outside the application.

;JOOP!
0
 
sciuriwareCommented:
The solution by Thomas4019 is uncertain: when 2 programs start at the same time they may 'think' that they are alone.
A lock is (as they call it) an atomic operation.
;JOOP!
0
 
mnrzCommented:
I think using a socket is better

public static void main(String[] args) 
{ 
        try 
        { 
                java.net.ServerSocket ss = new java.net.ServerSocket(9955); //some port 
        } 
      catch (java.net.BindException ex) 
        { 
                System.out.println("Program is already running!"); 
                System.exit(1); 
        } 
      catch (java.io.IOException ex) 
        { 
                ex.printStackTrace(); 
                System.exit(1); 
        } 
        System.out.println("Program is starting for the first time....
");
}

Open in new window

0
 
sciuriwareCommented:
Yes but which socket numbers are guaranteed not in use by some other utility?

;JOOP!
0
 
mnrzCommented:
Yes you're right. but there are lots of applications that use a specific port number. if a non typical port is used, rarely will a conflict happen. in an advanced program you may set the port number during the installation like many others...
0
 
sciuriwareCommented:
. what's non-typical?

A lockfile is visible and can even contain the ID of the program,
so you can know which lockfile belongs to which program.

But, it's your choice, most of the time both solutions will work.
Some methods in my solution make group-locking or per-user locking possible.

;JOOP!
0
 
avya2kCommented:
This would work
public static void chkInstances() throws Exception {
		File marker = new File("C:/running.txt");
		System.out.println(marker.exists());
		if (marker.exists()) {
			JOptionPane.showMessageDialog(null, "Program already running!");
			System.exit(0);
		}
 
		marker.createNewFile();
		marker.deleteOnExit();
		Thread.sleep(5000);
		// ONLY ONE INSTANCE IS NOW RUNNING
		// YOUR CODE HERE
	}

Open in new window

0
 
avya2kCommented:
Thread .sleep is just to chk if it is working you can remove it
0
 
avya2kCommented:
in this problem if ur program gets terminated and jvm shuts down abruptly then only it caues problem
Other way round is to listen to a port automatically second instance will terminate as only one program can listen to that port
If any arbitrary program blocks your port then you might not detect if your program is running or some other program is running on that port
0
 
sciuriwareCommented:
So ........................... use the lock file instead.
Thank you.

;JOOP!
0
 
avya2kCommented:
This can be the final solution
In port and handshake you can put any arbitrary value from properties file.
can be called like InstanceKiller.chkInstance();
class InstanceKiller implements Runnable{
	private static int port=4865;
	private static ServerSocket ssock=null;
	private static String handshake="HI";
	
	public static void chkInstance() {
		Socket sock=null;		
		try{
			ssock=new ServerSocket(port);
			System.out.println("Listeneing to port:"+port);
			new Thread(new InstanceKiller()).start(); 
		}catch(BindException be){
			System.out.println("Program might be running");
		}catch(IOException ioe){}
		try{
			if(ssock==null){
				sock=new Socket("localhost", port);
				sock.getOutputStream().write(handshake.getBytes());
				while(sock.getInputStream().available()<1);
				byte[] b=new byte[sock.getInputStream().available()];
				sock.getInputStream().read(b);
				if(handshake.equals(new String(b))){
					System.out.println(new String(b));
					System.out.println("This is my program so can exit now");
					System.exit(0);
				}
			}
		}catch(UnknownHostException unhe){}
		catch(IOException ioe){}
		
	}
	public void run(){
		Socket s=null;		
		while(true){
			try{
				s=ssock.accept();
				while(s.getInputStream().available()<1);
				byte[] b=new byte[s.getInputStream().available()];
				s.getInputStream().read(b);
				if(handshake.equals(new String(b)))
					s.getOutputStream().write(handshake.getBytes());
			}catch(Exception e){}
		}
	}
}

Open in new window

0
 
avya2kCommented:
This has only flaw that if another program is running on your port then you should be change the port for first time
0
 
avya2kCommented:
This has only flaw that if another program is running on your port then you should be change the port for first time but this would be very rare situation if you select the port like 10000 or higher
0
 
tia_kamakshiAuthor Commented:
Many Thanks to you all.

I am sorry for delay response, I was out on Easter holidays. Just came today

I will check and come back to you.

Many Thanks again
0
 
tia_kamakshiAuthor Commented:
Hi,

Many Thanks for your response.

I am now trying to work with both solutions
--> Solitarity.java -- > which locks the file
--> InstanceKiller.java --> using ports

But in both of these solutions, I am getting hard time to use with my TimerTest.java

Which is very simple test file

Can you please help me in using your codes

I will check and come back to you

Many Many Thanks for your co-operation
InstanceKillerjava.txt
Solitarityjava.txt
TimerTestjava.txt
0
 
sciuriwareCommented:
Fill in the name of your program in the class.

Then call:

   Solitarity.solitaire();   // To set the locking

   Solitarity.unsolitaire();  // To release the lock prematurely.
// Or just exit.

A way to get the name of your program from java is:

   /**
    * Returns the program name (=main class name).
    * <P>
    * Determines the name of the first class loaded for this program by means of a probing Exception.<BR>
    * The name is saved, so the evaluation is performed only once.
    * </P>
    *
    * @return the name of the program.
    */
   public static String getProgramName()
   {
      if(programName == null)
      {
         try
         {
            throw new Exception();
         }
         catch(Exception e)
         {
         StackTraceElement[] u = e.getStackTrace();

            programName = u[u.length - 1].getClassName();
         }
      }
      return(programName);
   }

;JOOP!
0
 
tia_kamakshiAuthor Commented:
Many Thanks. It works

I am also looking solution with socket. How do we use solution from given by avya2k

I have attached file "InstanceKillerjava.txt" (InstanceKiller.java )

Please guide me how to use that as well

Many Thanks

0
 
tia_kamakshiAuthor Commented:
Many Thanks
0
 
sciuriwareCommented:
:)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.