Solved

To stop running another instance of my java program

Posted on 2009-04-10
24
1,014 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
ID: 24117047
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
ID: 24117059
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
ID: 24117087
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
PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

 

Author Comment

by:tia_kamakshi
ID: 24117255
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
ID: 24117526
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
ID: 24117534
A singleton will not help you as it is unknown outside the application.

;JOOP!
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 24117546
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
ID: 24117627
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
ID: 24117649
Yes but which socket numbers are guaranteed not in use by some other utility?

;JOOP!
0
 
LVL 8

Expert Comment

by:mnrz
ID: 24117713
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
ID: 24117895
. 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
ID: 24129686
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
 
LVL 5

Expert Comment

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

Expert Comment

by:avya2k
ID: 24129772
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
ID: 24129935
So ........................... use the lock file instead.
Thank you.

;JOOP!
0
 
LVL 5

Expert Comment

by:avya2k
ID: 24135031
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
ID: 24135034
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
ID: 24135037
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
ID: 24135879
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
ID: 24146191
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
ID: 24146312
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
ID: 24147971
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
ID: 31568971
Many Thanks
0
 
LVL 24

Expert Comment

by:sciuriware
ID: 24156666
:)
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Checkbox and ListView in Android Layout 4 68
web application structure 18 77
hibernate insert example 13 29
hibernate jars 4 32
Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers learn how to read error messages and identify possible mistakes that could cause hours of frustration. Coding is as much about debugging your code as it is about writing it. Define Error Message: Line Numbers: Type of Error: Break Down…

832 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