I have a jar file that displays a JFrame when it is executed.
I don't want to allow duplicate execution of my Jar file.
Every time before creating the frame, using Java I want check whether the Jar is already executing. If my app. already has an instance on-screen, I want to bring it to front.
How can I do that?
Please suggest me a way.
There is no regular method in java for single instance of an application.
However you can use Socket programming technique to achieve your goal.
When the instance is creating it attempts to listen a ServerSocket. If it could open the ServerSocket it means there are no another instance of the application. So, it keeps the ServerSocket live until the program is shutdown. If it could not open the ServerSocket, it means the application already have another instance. So you can exit application silently. Additionally you don't need to reset your settings when shutdown the application.
Try following example
public class SingletonApplication extends JFrame implements Runnable {
//count of tried instances
private int triedInstances = 0;
//the port number using
private static final int PORT = 5555;
public static void main(String[] args) {
SingletonApplication application = new SingletonApplication();
application.setTitle("My Singleton Application");
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.setSize(500, 500);
application.setVisible(true);
}
public SingletonApplication() {
super();
//run socket listening inside a thread
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
try {
//create server socket
ServerSocket serverSocket = new ServerSocket(PORT);
//listing the socket to check new instances
while (true) {
try {
//another instance accessed the socket
serverSocket.accept();
//bring this to front
toFront();
//change the title (addtional);
triedInstances++;
setTitle("Tried another instances : " + triedInstances);
} catch (IOException ex) {
//cannot accept socket
}
}
} catch (IOException ex) {
//fail if there is an instance already exists
try {
//connect to the main instance server socket
new Socket(InetAddress.getLocalHost(), PORT);
} catch (IOException ex1) {
//do nothing
} finally {
//exit the system leavng the first instance
System.exit(0);
}
}
}
}
EDIT:
Additionally: It can pass your runtime arguments into the main instance of the application via the client Socket. So, it's possible to make the main instance to perform required task such opening file or playing music by adding some additional code to read the InputStream of accepted Socket when calling accept() method.
I had the same situation.
What I did is I used to open a file in write mode and delete the file when I close the application.
By doing this I have a known proof that my program is running.
Each time I open the application I check for the existence of that file and if I find my file, it is running then I used to alert him
"An instance is already running".
Even if one tries to delete that file it says that it is open in another application.
I used a socket too, via RMI.
The application is an RMI host/server, accepts a Remote Method Invokation on a port.
In the main, at startup on tries as RMI client to get an RMI server on that port.
Is it there one does a remote call passing the command line args (to open another document for instance). And then quits.
As a server on being called that remote method one brings the application to front using toFront() of the window.
JUnique accomplishes the first part--blocking multiple instances of the same program. Getting the existing instance to come to the front is another task that I'm not sure how to approach.
Related
We're working on a school project where we have to use Telnet (Yes, I know, we shouldn't use it etc., but we have to) to communicate between a server and a client. We have two classes setup, a server and a client, which is a thread. We called our client 'NetManager', it can send and receive messages.
However, we have other classes as well which need to send messages to the server, and handle the output the server returns. We want to do this via the NetManager, instead of setting up a new Thread and socket for each class individually.
However, we do not know how to do this. Ideally we want to have a while(working) { } in our NetManager class which reads the lines the server sends, but we also need to send messages inside the while loop. The messages needs to vary so simply putting them in the while loop won't work. Is there a way to do server-client communication, where multiple classes use the NetManager class to send and receive messages from a server?
I have included a stripped down version of our NetManager class below for reference. This version only reads lines sent by the server, it does not yet send messages (which could be accomplished with out.println();
.
public class NetManager extends Thread {
private BufferedReader in;
private BufferedReader stdIn;
private PrintWriter out;
private String line;
#Override
public void run() {
boolean working = true;
try {
Socket sock = new Socket("localhost", 7789);
out = new PrintWriter(sock.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (working) {
try {
line = in.readLine();
System.out.println(line);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Here is a quick scheme I made of the best case scenario:
While I think your design is a good one I also think it may be overly complicated for what you are trying to do. If multiple classes are going to be using the same NetManager instance then you are going to have to implement some sort of locking and/or queuing so only one class tries to access NetManager at a time. Then you will also have to figure out some way to make sure any response received by NetManager gets back to the appropriate caller.
Having said all that, I would have any classes that use NetManager accept an instance of it in the constructor. It would then save a reference to the object and use it as necessary.
Currently I am working on Java client/server chat app and got one question, I'll try to explain as clear as possible.
My server part keeps creating threads (new ServerThread) for each user who comes online:
while (isRunning) {
Socket socket = serverSocket.accept();
DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
outputStreams.put(socket, dout);
System.out.println (outputStreams.values());
new ServerThread(this, socket);
window.newConnectionInfo(socket);// informace
}
I have a getter method in a ServerThread class, which I want to call from the certain ServerThread instance based on socket. But ServerThread class isn't assigned to any variable, so I don't know exactly how to call methods from it. Any solution on that?
Easy, you need to locate and find the thread you want to force call a method, that you would keeps every thread you create, I suggest you the Map you are using for keeping clients would be in < ServerThread ,DataOutputStream >, so here you have all threads now (and Scoket instance inside the ServerThread), okay and the answer.
okay first you need a method for signalling the target thread in the ServerThread, like this
class ServerThread{
public void forceToCall(Object o){//an object argument, would be void too, or an interface
//do something, call someone
}
}
then, so who is going to call this method? simply create a class that would call the target client sync or async mode, just like this
class ClientMethodCaller implements Runnable{
ServerThread st;Object arg
public ClientMethodCaller(ServerThread st,Object arg){this.st=st;this.arg=arg;}
public void run () {
st.forceToCall(arg);//signalling the client async
}
}
and at the end, whenever you want to a client to run a specific method, just after finding the client(ServerThread) instance, call the target method by ClientMethodCaller
ServerThread st;//got the instance
new Thread(new ClientMethodCaller(st,"Hello!")).start();
and the final word, this is not good, running a thread for any client logins, IF the program, is not small and the number of users are to much.
also check this tutorial too, would help
I saw plenty of similar questions on SO but hardly any of them have Socket in the picture. So please take time to read the question.
I have server app (using ServerSocket) which listens for requests, and when a client attempts to connect, new thread is created to serve the client (and server is back to listening mode for new requests). Now, I need to respond one client based on what other client sent to server.
Example:
ServerSocket listening for incoming connections.
Client A connects, new thread is created to serve A.
Client B connects, new thread is created to serve B.
A sends message "Hello from A" to the Server.
Send this message as a response to Client B.
I'm new to this whole "inter-thread communication" thing. Obviously, above mentioned situation sounds dead simple, but I'm describing this to get a hint, as I'll be exchanging huge amount data among clients keeping server as intermediate.
Also, what if I want to keep a shared object limited to, say 10, particular Clients? such that, when 11th client connects to the server, I create new shared object, which will be used to exchange data between 11th, 12th, 13th..... upto 20th client. And so on for every single set of 10 clients.
What I tried: (foolish I guess)
I have a public class with that object supposed to be shared as public static, so that I can use it as global without instantiating it, like MyGlobalClass.SharedMsg.
That doesn't work, I was unable to send data received in one thread to the other.
I'm aware that there is an obvious locking problem since if one thread is writing to an object, other can't be accessing it until the first thread is done writing.
So what would be an ideal approach to this problem?
Update
Since the way in which I create threads for serving incoming connection requests, I can't understand how I can share same object among the threads, since using Global object as mentioned above doesn't work.
Following is how I listen for incoming connections and create serving threads dynamically.
// Method of server class
public void startServer()
{
if (!isRunning)
{
try
{
isRunning = true;
while (isRunning)
{
try
{
new ClientHandler(mysocketserver.accept()).start();
}
catch (SocketTimeoutException ex)
{
//nothing to perform here, go back again to listening.
}
catch (SocketException ex)
{
//Not to handle, since I'll stop the server using SocketServer's close() method, and its going to throw SocketException anyway.
}
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
else
System.out.println("Server Already Started!");
}
And the ClientHandler class.
public class ClientHandler extends Thread
{
private Socket client = null;
private ObjectInputStream in = null;
private ObjectOutputStream out = null;
public ClientHandler(Socket client)
{
super("ClientHandler");
this.client = client;
}
//This run() is common for every Client that connects, and that's where the problem is.
public void run()
{
try
{
in = new ObjectInputStream(client.getInputStream());
out = new ObjectOutputStream(client.getOutputStream());
//Message received from this thread.
String msg = in.readObject().toString();
System.out.println("Client # "+ client.getInetAddress().getHostAddress() +" Says : "+msg);
//Response to this client.
out.writeObject("Message Received");
out.close();
in.close();
client.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
I believe that the way I'm creating dynamic threads to serve each client that connects, sharing the same data source is not possible using Global object, since the body of run() above is exactly the same for every client that connects, hence this same method is both consumer and producer. What fixes should I make such that I could create dynamic threads for each connection and still share the same object.
You probably want a queue for communication between each client. Each Queue will be the 'pipeline' for data pushed from one client to the other.
You would use it like so (pseudo code):
Thread 1:
Receive request from Client A, with message for Client B
Put message on back of concurrent Queue A2B
Respond to Client A.
Thread 2:
Receive request from Client B.
Pop message from front of Queue A2B
Respond to Client B with message.
You might also want it generic, so you have a AllToB Queue that many clients (and thus many threads) can write to.
Classes of note: ConcurrentLinkedQueue, ArrayBlockingQueue.
If you want to limit the number of messages, then ArrayBlockingQueue with its capacity constructor allows you to do this. If you don't need the blocking functionality, you can use the methods offer and poll rather than put and take.
I wouldn't worry about sharing the queues, it makes the problem significantly more complicated. Only do this if you know there is a memory usage problem you need to address.
EDIT: Based on your update:
If you need to share a single instance between all dynamically created instances you can either:
Make a static instance.
Pass it into the constructor.
Example of 1:
public class ClientHandler extends Thread
{
public static final Map<ClientHandler, BlockingQueue<String>> messageQueues
= new ConcurrentHashMap<>();
<snip>
public ClientHandler(Socket client)
{
super("ClientHandler");
this.client = client;
// Note: Bad practice to reference 'this' in a constructor.
// This can throw an error based on what the put method does.
// As such, if you are to do this, put it at the end of the method.
messageQueues.put(this, new ArrayBlockingQueue<>());
}
// You can now access this in the run() method like so:
// Get messages for the current client.
// messageQueues.get(this).poll();
// Send messages to the thread for another client.
// messageQueues.get(someClient).offer(message);
A couple of notes:
The messageQueues object should really contain some sort of identifier for the client rather than an object reference that is short lived.
A more testable design would pass the messageQueues object into the constructor to allow mocking.
I would probably recommend using a wrapper class for the map, so you can just call offer with 2 parameters rather than having to worry about the map semantics.
I'm new to Java Socket Programming and currently exploring its Socket APIs. I've created a new simple App that starts ServerSocket and listens for Clients, when client writes something on the socket, server allocates new thread for that client. I tried first using console app and everything worked fine. Now, I've made GUI for the same using SWT (WindowBuilder plugin in Eclipse 3.7). The Window has a button which toggles listening of the server On and Off. Below is the code written in SWT Button's click event which will start listening for clients.
if(!isServerRunning)
{
btnServerRunner.setText("Stop Server");
isServerRunning = true;
while (listening)
{
try
{
new ClientHandler(listener.accept()).start();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
else
{
try
{
listener.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
btnServerRunner.setText("Start Server");
isServerRunning = false;
}
The ClientHandler class has Thread extended and hence will launch new thread for every new client. I know above code works for console app but will not work for GUI since I'm throwing app into infinite loop of listening for client sockets in button's click. What is the elegant way to start and stop ServerSocket for listening for clients that doesn't freeze the app UI?
Thanks.
You should use a separate thread for accepting client connections. The button could just start and interrupt that thread.
You need to run your Server in a separate thread (from the UI dispatch thread).
i have a java project, works as a server. when an instance of this project running, i can run another instance.
how can i avoid running of more than one instance on same java project at the same time?
(Stop the server when another instance is detected)
import java.net.ServerSocket;
.....
private static final int PORT = 9999;
private static ServerSocket socket;
public static void main(String[] args) {
try {
socket = new ServerSocket(PORT, 0, InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }));
{/*here write your own code taht must be run in the main*/}
} catch (BindException e) {
System.err.println("**********************************Already running.");
System.exit(1);
} catch (IOException e) {
System.err.println("************************************Unexpected error.");
e.printStackTrace();
System.exit(2);
} catch (Exception e) {
System.err.println("************************************ Error");
System.exit(3);
}
}
i used this code and it work try it
Easiest way is to use lock file, this causes problems if the app crashed. Try writing the pid into the lock file, you can check if that pid exists (although not natively maybe in a wrapper shell script).
If you are running server can you not check if a port is open, or better still maybe a jmx instance on a known port.
I totally support #vickirk - his approach allows the second "un-needed" instance of your server become "dormant" instead of simply terminating, i.e. periodically run to perform a check if the "active" instance is still actually active/present, and take over if it went down.
In the distrubuted case, if the requirement is to have a single server instance spanning multiple machines, the approach is still to find a common resource that can be locked, physically or logically. For that purpose, I personally use a control database table where an active process writes its PID and "heartbeat", and all others are checking for that "heartbeat" to be fairly recent, and become active if its not.
you can write simple command line script for app start - that check is server runs before actually run new instance. Just check url with wget for example...