Hi guys...

Is it possible to stop opening multiple instance of a jar file...

I just want to open my application only one (only one instance) at a time.

Bind a ServerSocket. If it fails to bind then abort the startup. Since a ServerSocket can be bound only once, only single instsances of the program will be able to run.

And before you ask, no. Just because you bind a ServerSocket, does not mean you are open to network traffic. That only comes into effect once the program starts "listening" to the port with accept().

Comments
Nice.

You can use a lock file in your base directory as well. We use that here at work for one particular app that should only be running a single instance.

I hadn't thought about a socket binding though. Interesting alternative.

lockfiles are extremely risky.
What if the running instance of the application crashes (or the computer it's running on crashes which has the same effect)?

The lockfile will still be there when you start it again, causing it to never start until the file is manually removed.
And what if some smartass finds out where the file is and removes it while the application is running? Now he can run as many instances as he wants side by side.

lockfiles are extremely risky.
What if the running instance of the application crashes (or the computer it's running on crashes which has the same effect)?

The lockfile will still be there when you start it again, causing it to never start until the file is manually removed.

Yes, depending on how you implement it, that is a risk. My code opens a FileChannel and obtains a lock with tryLock(). If the app crashes, this lock is lost. It deletes the existing lock file if one is present, so it doesn't really care if a previous lock was already there. I haven't been able to break it so far, but that doesn't mean it's bulletproof :)

try {
    lockFile = new File( env , "transport.lock");
    if (lockFile.exists())
        lockFile.delete();
    FileOutputStream lockFileOS = new FileOutputStream(lockFile);
    lockFileOS.close();
    lockChannel = new RandomAccessFile(lockFile,"rw").getChannel();
    lock = lockChannel.tryLock();
    if (lock==null) throw new Exception("Unable to obtain lock");
} catch (Exception e) {
    JOptionPane.showMessageDialog(this,"An instance of Job Selector is already running.","Warning",JOptionPane.WARNING_MESSAGE);
    e.printStackTrace();
    System.exit(0);
}

And what if some smartass finds out where the file is and removes it while the application is running? Now he can run as many instances as he wants side by side.

The file can't be deleted due to the lock in this case.

It works for us, but then I never though about the socket binding thing, so that may be an even easier and more well-behaved way to go about it.:)

Glad it works for you. Keep in mind the points jwenting mentioned though. I don't think you will have those issues with the code I pasted, but testing is your best friend.

Be sure you release the lock and close the channel when you no longer need them:

lock.release();
lockChannel.close();
lockFile.delete();

The file can't be deleted due to the lock in this case.

That depends on the operating system and the user permissions on that operating system...
On Windows it's indeed hard (but not imposssible) to remove an open file, on Linux it's quite possible.

Glad it works for you. Keep in mind the points jwenting mentioned though. I don't think you will have those issues with the code I pasted, but testing is your best friend.

Be sure you release the lock and close the channel when you no longer need them:

lock.release();
lockChannel.close();
lockFile.delete();

yea i have used all these... but if i rename the jar file means its worthless... its again opening multiple instances

here is my code...

try {
        // Get a file channel for the file
        File file = new File("filename");
        FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
    
        // Use the file channel to create a lock on the file.
        // This method blocks until it can retrieve the lock.
        FileLock lock = channel.lock();
    
        // Try acquiring the lock without blocking. This method returns
        // null or throws an exception if the file is already locked.
        try {
            lock = channel.tryLock();
        } catch (OverlappingFileLockException e) {
            // File is already locked in this thread or virtual machine
        }
    
        // Release the lock
        lock.release();
    
        // Close the file
        channel.close();
    } catch (Exception e) {
    }

Edited 5 Years Ago by peter_budo: Adding code tags to old post

Go back to reply number 1.

i dont have any idea about server socket thats why looking for alternate solution....

So read a quick Networking tutorial on Sun. They are easier to use than the lockfile routine you just tried.

Then again, you didn't write that code.

Read the networking tutorial, give the ServerSocket a try, then, if it doesn't work, post your code here and we will help you correct it.

That depends on the operating system and the user permissions on that operating system...
On Windows it's indeed hard (but not imposssible) to remove an open file, on Linux it's quite possible.

Yes, that could be quite possible. All of our users for this app are on Windows, so no testing of the lock scheme has been done on Linux or Mac. In our case, it's not really a big concern since having multiple instances running will only cause them confusion, not critical application problems or a security risk.

It's good to know about the potential problems that might occur on they other OSs though, for future references. Thanks for the input :)

Maybe this should be a good starting point:

// Untested

import java.net.*;
import java.io.*;

public class A
{
    public static void main(String args[])
    {
        try
        {
            ServerSocket ss = new ServerSocket();
            ss.bind(new InetSocketAddress(100));
            System.out.println("Application started");
            Thread.sleep(1000000000);
        }
        catch (SocketException e)
        {
            System.out.println("Application already running");
            System.exit(1);
        }
        catch(Exception e)
        {
            System.out.println("Application encountered some problem.");
            System.exit(1);
        }
    }
}

It works!!!!
hey thank u all.

But now I want to do the following things

--> whenever user try to run second instance of the application.. the first running application got focused automatically.... LIKE MS WORD... If I opened 1.doc and try to reopen 1.doc the first 1.doc which is already opened got focus and maximize automatically or the title bar color changed to yellow....

pls give me reply asap as possible

Then actually use that socket, and have the "second" one simply send a "message" to it and have the "first" react to that.

I know this is old thread, but I couldn't resist to share my finding. As OP I was looking for concept to prevent a user to run simultaneously more instances of the same Java application, and I came across of this library JUnique

Happy coding!

This question has already been answered. Start a new discussion instead.