Solved

To stop running another instance of my java program

Posted on 2009-04-10
24
1,012 Views
Last Modified: 2012-05-06
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

0
Comment
Question by:tia_kamakshi
  • 10
  • 6
  • 5
  • +2
24 Comments
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
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
 
LVL 24

Accepted Solution

by:
sciuriware earned 500 total points
Comment Utility
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
 
LVL 17

Expert Comment

by:Thomas4019
Comment Utility
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
 

Author Comment

by:tia_kamakshi
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
A singleton will not help you as it is unknown outside the application.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
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
 
LVL 8

Expert Comment

by:mnrz
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
Yes but which socket numbers are guaranteed not in use by some other utility?

;JOOP!
0
 
LVL 8

Expert Comment

by:mnrz
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
. 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
 
LVL 5

Expert Comment

by:avya2k
Comment Utility
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
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 5

Expert Comment

by:avya2k
Comment Utility
Thread .sleep is just to chk if it is working you can remove it
0
 
LVL 5

Expert Comment

by:avya2k
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
So ........................... use the lock file instead.
Thank you.

;JOOP!
0
 
LVL 5

Expert Comment

by:avya2k
Comment Utility
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
 
LVL 5

Expert Comment

by:avya2k
Comment Utility
This has only flaw that if another program is running on your port then you should be change the port for first time
0
 
LVL 5

Expert Comment

by:avya2k
Comment Utility
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
 

Author Comment

by:tia_kamakshi
Comment Utility
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
 

Author Comment

by:tia_kamakshi
Comment Utility
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
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
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
 

Author Comment

by:tia_kamakshi
Comment Utility
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
 

Author Closing Comment

by:tia_kamakshi
Comment Utility
Many Thanks
0
 
LVL 24

Expert Comment

by:sciuriware
Comment Utility
:)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This was posted to the Netbeans forum a Feb, 2010 and I also sent it to Verisign. Who didn't help much in my struggles to get my application signed. ------------------------- Start The idea here is to target your cell phones with the correct…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now