I need to have only one instance of a Desktop GUI application running.
What is the best way to do this? The only answer I can find
searching throught the archives was to use a socket. Is this the best
way?
I thought about using rmi (registry) and binding a unique name however
the problem is if the appliction start the registry, when it exits, it
takes the registry down with it.
Is there a cleaner way to do this. I've seen this in several IDE(s)
Eclipse and JBuilder. How is it done in those apps?
Thanks in advance,
Kent
use a small server program. open a port. ( less than 20 lines of code)
when you launch your app , check if you get an answer on the port, if so
there is already an app running.
if not then launch a small server.
DO NOT use a flag file, if your app crashes or the disk gets corrupted, all
sorts of things can happen. ( i have tired many different forms of flag files
etc, but there is always one user who manages to beat the system, or corrupt
it)
With the server method, it always cleans up on the JVM exit, same with a
crash.
JustOne StartTracker = new JustOne();
if (StartTracker.doit() == false) {
try {
.........
program call routines
}
}
else
//it is already running so exit
StartTracker.stopTask();
System.exit(1);
}
package SimpleServer;
import java.io.*;
import java.net.*;
//this package starts a java server listening on port 8181
//it does this to stop the java program from being launched more than once
// as the user only needs 1 copy running, also it causes client memory
issues. if
//more than 1 copy of the program is running
public class SimpleServer extends Thread {
public static final int port = 8181;
ServerSocket serverSocket = null;
Socket clientSocket = null;
public void run() {
try {
// Create the server socket
serverSocket = new ServerSocket(port, 1);
while (true) {
// Wait for a connection
clientSocket = serverSocket.accept();
// System.out.println("*** Got a connection! ");
clientSocket.close();
}
} catch (IOException ioe) {
System.out.println("Error in SimpleServer: " + ioe);
System.exit(0); // we can do nothing else
}
}
}
package Server;
import SimpleServer.*;
import java.io.*;
import java.net.*;
//we have not started the error logger yet, ( we cannot, in case there is a
second instance running
//therefore we have to rely on the normal system errror caller
public class JustOne {
SimpleServer sds = null;
boolean keepRunning = true;
private boolean status = true; //say it is already running
private Runnable r = null;
//this is to be called when the program finally exits.
public void stopTask() {
keepRunning = false;
}
public boolean doit() {
status = false; // say it is only the first copy
try {
Socket clientSocket = new Socket("localhost",
SimpleServer.port);
status = true;
} catch (Exception e) {
//this starts a new thread before the modal
r = new Runnable() {
public void run() {
newServer();
}
};
new Thread(r).start();
status = false; // say it is only the first copy
}
// finally {
return status;
// }
}
public void newServer() {
sds = new SimpleServer();
sds.start();
while (keepRunning == true) {
try {
// System.out.print(".");
Thread.sleep(5 * 60);
} catch (Exception e) {
e.printStackTrace();
System.exit(0); // we can do nothing else
}
}
}
}