I am trying to build an application where the server is a bank and the clients are the bracnhs of that bank so it's classic Multithread server / client app. In the first step i want the bank to record every branch that connects to it. so iwant to send the branck as object in the objectstream of the socket so that the bank can extract it and record it.
here's what i have done so far
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Banque {
private List<Succursale> listSucc = new ArrayList<Succursale>();
private int sommeTotale;
private int nbSuccInit = 4;
public void ajouteSucc(Succursale suc){
}
public Banque(){
initialiserServeur();
}
private void initialiserServeur() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(10118);
}
catch (IOException e)
{
System.err.println("On ne peut pas ecouter au port: 10118.");
System.exit(1);
}
System.out.println ("Le serveur est en marche, Attente de la connexion.....");
int i = 0;
while(i<5){
try {
UtilMultiTh mt = new UtilMultiTh(serverSocket.accept());
Thread t = new Thread(mt);
t.start();
listSucc.add(mt.getSuc());
System.out.println(listSucc.size());
for(int j =0; j<listSucc.size();j++){
System.out.println("La succursale "+(j+1)+" est:"+listSucc.get(j).getName());
}
i++;
System.out.println("FLAGPOSTban");
}
catch (IOException e)
{
System.err.println("Accept a echoue.");
System.exit(1);
}
}
System.out.println ("connexion reussie");
System.out.println ("Attente de l'entree.....");
}
public static void main (String [] args){
Banque banK = new Banque();
}
}
The class MultiTh that manage the multi thread connection of the branchs
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.*;
public class UtilMultiTh implements Runnable {
private Socket soc;
private Succursale suc;
public UtilMultiTh(Socket s){
System.out.println("FLAGconsmth");
this.soc = s;
}
public void run() {
System.out.println("FLAGPOSrun");
ObjectOutputStream oos;
ObjectInputStream ois;
try{
oos = new ObjectOutputStream(soc.getOutputStream());
ois = new ObjectInputStream(soc.getInputStream());
//System.out.println("La succ est");
try {
Object o = ois.readObject();
if(o!=null){
suc = (Succursale)o;
//System.out.println("La succ est"+suc.getName());
}
/*while(o!=null){
suc = (Succursale)o;
System.out.println("La succ est"+suc.getName());
}*/
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
oos.close();
ois.close();
soc.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public synchronized Succursale getSuc() {
return suc;
}
public void setSuc(Succursale suc) {
this.suc = suc;
}
}
And here's the Succursale class for the branchs
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class Succursale implements Serializable {
private String coordonnees;
private String name;
private int sommeDepart;
private int sommeRecue;
private int sommeEnvoyee;
private List<Succursale> listSuccAc = new ArrayList<Succursale>();
private GuiSuccursale succView;
public Succursale (){
succView = new GuiSuccursale(Constantes.sommeDepart,1);
this.sommeDepart=Constantes.sommeDepart;
this.name="Succursale: "+(1);
connexionBanque();
}
public void connexionBanque(){
String host = Constantes.adrBanque[0];
int port = Constantes.portBanque[0];
Socket echoSocket = null;
try {
echoSocket = new Socket(host, port);
ObjectOutputStream oos = new ObjectOutputStream(echoSocket.getOutputStream());
oos.writeObject(this);
System.out.println("FLAGPOSTSUcc");
} catch (UnknownHostException e) {
System.err.println("Hôte inconnu: " + host);
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Ne pas se connecter au serveur: " + host);
System.exit(1);
}
}
public void connexionSuccursales(){
}
public void envoiManuel(){
}
public String getName() {
return name;
}
public void envoiPeriodique(){
}
public static void main (String[] args){
Succursale suc = new Succursale();
}
}
I have two questions, how can i from the UtilMultuTh return a Succursale to Banque and before that why is that in the UtilMultiTh class readObject return null while in the succursale class just after etablishing the connection i put the class in the socket ? Do i have to put an infinite loop in here ?
EDIT: I changed the code, now multith is correctly getting the Succursale from the socket, the problem now is that the threads are no synchronised because UtilMultiTh gets the Succursale after Banque wants to get it, i am not familiar with synchrnosation, how can i tell Banque to do the getSuccursale only after utilMultiTh performed its run ?
Google's protobufs are perfect for this. I'd suggest using them and sending the byte output between client and server. You'll need to frame your output if you're planning to use TCP.
Java's serialization mechanism could always break between different runtime versions. Also, what if you decide to implement the server or client in another language? You'll have to duplicate java's entire serialization logic. Protobuf takes care of the tedious process required to marshall and unmarshall objects to and from bytes. So pretty much, its a better form of java's built in serialization which is language independent.
So I suggest you abandon Object streams. I know this isn't the answer you were hoping for, but it will make things nicer for you in the long run.
ProtoBuffers
This is not an answer to you question, but it won't fit in a comment and I think it needs to be said.
Be sure to reset your output stream after each write! ObjecdtOutputStream only writes an object once. If you try to write it again, it will just send a little note "Put that object I sent a while ago in back the input stream again at this point." Saves space, but if your object has changed, those changes won't get through. Also, the original object sent is going to be kept in memory on both sides, killing your performance. Reset clears everything out and gives you a fresh start.
Also, I'd use Externalizable rather than Serializable. This gives you control over what is sent (though you have to write some code). There is some danger that if you write an object that refers to other objects it will write all those other objects as well, which you may not want. Also, Externalizable lets you write to the same, old format even if the class changes. Also, it lets you put in version numbers. These can sometimes allow a newer version to read a stream written by an older version, but it always gives you a warning that the format has changed.
The intent of ObjectOutputStream is that you can write one object that includes all your data. A truly vast graph can be sent with one call to writeObject. This is ingenious. It worked fine for me, writing the complete state of a computer game to a disk file with one writeObject( this ), but it's usually a disaster when writing to a socket.
I am somewhat inclined not to use ObjectOutput, but to just write primitives. It's simpler and faster and you have a lot of control. But I have had trouble knowing which object to create on the Input end. I think the best thing to do is read and write objects, but keep the I/O simple by writing your own method for the Externalizable interface and calling reset() after each writeObject.
Related
I am developing a Client-Server application with several other programmers, in Java. At this point in time I do not want to be running the code locally. I want to be able to connect to the Server from any machine.
I wrote a test server and test client, just to make sure that things are working properly. But they are not. I am using Amazon AWS EC2 Linux that comes with Java. I am able to compile and run my Server after I SSH into the EC2, but the Client on my local disk is just not connecting. Here is the code.
// Code found online (https://cs.lmu.edu/~ray/notes/javanetexamples/)
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class TestServer {
public static void main(String[] args) throws Exception {
try (ServerSocket listener = new ServerSocket(50000)) {
System.out.println("The capitalization server is running...");
System.out.println(listener.getInetAddress());
ExecutorService pool = Executors.newFixedThreadPool(20);
while (true) {
pool.execute(new Capitalizer(listener.accept()));
}
}
}
private static class Capitalizer implements Runnable {
private Socket socket;
Capitalizer(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
System.out.println("Connected: " + socket);
try {
Scanner in = new Scanner(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (in.hasNextLine()) {
out.println(in.nextLine().toUpperCase());
}
} catch (Exception e) {
System.out.println("Error:" + socket);
} finally {
try { socket.close(); } catch (IOException e) {}
System.out.println("Closed: " + socket);
}
}
}
}
// Code found online (https://cs.lmu.edu/~ray/notes/javanetexamples/)
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class TestClient {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket("ADDRESS HERE", 50000)) {
System.out.println("Enter lines of text then Ctrl+D or Ctrl+C to quit");
Scanner scanner = new Scanner(System.in);
Scanner in = new Scanner(socket.getInputStream());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while (scanner.hasNextLine()) {
out.println(scanner.nextLine());
System.out.println(in.nextLine());
}
}
}
}
In place of "ADDRESS HERE" in the Client, I have tried the private IP and public IP of my Amazon EC2 instance. I have also tried the public DNS name. Nothing seems to work. There is just no connection from the Client to the Server. In fact, "Enter lines of text then Ctrl+D or Ctrl+C to quit" never prints.
All help is appreciated. Thank you.
Allow your IP address to send request to the EC2. For this, you need to go to your Security Group and add your IP there. Follow these steps-
GO to your AWS console.
Click on EC2, then under Resources you will find Security Groups.
Select your security group.
Follow the steps in the given image.
Since you're able to connect to EC2 instance via SSH, your Security Group allows this.
Now you need to allow requests from the client in this Security Group. You will either need to provide a concrete IP, IP range or allow all IPs (not recommended) in the group.
You can find how to do this here.
I am creating a Java HTTP server that checks to make sure a client is not banned before redirecting to the main server. I have already created everything for the server that is needed, I just don't know how to redirect to another port that is running the main server. Here is my code:
package netlyaccesscontrol;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class AllowedCheck {
public static void main(String[] args) {
String line = null;
try {
FileReader reader = new FileReader("Banned.txt");
BufferedReader buffer = new BufferedReader(reader);
ServerSocket s = new ServerSocket(80);
Socket c = s.accept();
String clientIP = c.getInetAddress().toString();
while ((line = buffer.readLine()) != null) {
if (clientIP == line) {
s.close();
} else {
// redirect to main server here
}
}
} catch (FileNotFoundException ex) {
System.out.println("The banned IP address file does not exist.");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
The redirection that you are thinking of is something supported by HTTP and the browsers. There's a specific HTTP response code that tells the caller to redirect and a way to specify it.
Raw sockets are a low-level network protocol that is not going to support redirection as you expect. The most you might be able to do is have this program be a proxy and, upon success, push all incoming data/outgoing responses to/from the ultimate server. But what you have here is by no means going to cut it.
I am completing an assignment for uni, we were given the source code for a minesweeper game and we have certain requirements to implement. One of these is that all games are read from disk after a user logs in, and users can save game progress at any time. I have been reading into serialization to save/load game progress but I am finding it a little hard to grasp the concept. I'm not exactly sure on where to start to write code for this. The game does not use a 2D array as a lot of other minesweeper games do. Can someone point me to any good documentation that is easy to understand, I find some webpages get a little too technical and I get lost! Or if anyone knows of a better way to save the progress of a minesweeper game? Sorry if my question is broad, I'm not 100% sure on what I should be reading to learn about this so that's why I'm asking for help, to get pointed in the right direction.
Basically you implement Serialization what forces you to convert all the objects it hold to a serialization process so it can be saved on memory.
Serialization is correctly implemented if used only on entities
class MinesweeperState implements Serializable {
private Board board;
}
class Board implements Serializable {
private int[][] mineTable;
}
And no more than sets and gets, the logic within initializating the table, filling the mines and setting its surrounding mine counters I would like to set on a Proxy or Adapter.
for the saving itself, just use a Manager with this code
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(YOUR_FILENAME_CONSTANT,false);
out = new ObjectOutputStream(fos);
out.writeObject(minesweeperState);
out.close();
System.out.println("Minesweeper state persisted");
} catch (IOException ex) {
LOGGER.err(ex);
}
You want to save all information that are related to the STATE that the game is in.
This means, game board (2D grid or however you store), player name, scores, etc.
The technical part about how to serialize an object is relatively easy... see http://www.javapractices.com/topic/TopicAction.do?Id=57.
However, you have to be careful with stuff like static or transient variables and know how these affect serialization (e.g. static class objects are not serialized but are lost).
Once you decide what needs saving, you can create a Class that contains variables/references to all the important objects - like a wrapper. This is if you want to avoid saving many different files.
You also need to add implements Serialiable to all the class definitions of objects that will be serialized.
So, in my example below we write the SavedState wrapper object, but as this contains Board, Board must also be serializable. You could write each object you want to save in a separate file but I prefer to have an object that holds all important information in 1 object/file because I find it is cleaner.
You then make assignments and write your object.
So Example:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
public class Game {
Board board;
String name;
public static void main(String[] args) {
Game game = new Game();
game.InitBoard();
//Now save the board
game.SaveBoard();
System.out.println("Player Name is:"+game.name);
System.out.println("Saved Board, changing in memory playername to 'test'.");
game.name = "test";
game.LoadBoard();
System.out.println("Loaded Board, Player Name is:"+game.name);
}
public void InitBoard()
{
board = new Board();
name = "player...";
}
public void SaveBoard()
{
try {
SavedState state = new SavedState(board, name);
OutputStream file = new FileOutputStream("game.mine");
OutputStream buffer = new BufferedOutputStream(file);
ObjectOutput output = new ObjectOutputStream(buffer);
output.writeObject(state);
output.flush();
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void LoadBoard()
{
SavedState state;
InputStream file;
try {
file = new FileInputStream("game.mine");
InputStream buffer = new BufferedInputStream(file);
ObjectInput input = new ObjectInputStream (buffer);
state = (SavedState)input.readObject();
this.board = state.board;
this.name = state.playerName;
input.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Board implements Serializable {
ArrayList<Integer> boardElements = new ArrayList<Integer>(); // or however
// else you
// store
// your
// values
// etc...
public Board() {
boardElements.add(1); // etc...
}
}
class SavedState implements Serializable {
Board board;
String playerName;
public SavedState(Board board, String playerName) {
this.board = board;
this.playerName = playerName;
}
}
What is the preferred way of passing data (a list of string) from a Java program to a Python script. The python script performs some processing on the data and then I need to get the results back in my Java program.
Is there is a framework that allows you to do this easily?
EDIT: More specific requirements.
My Java program is a scheduler (runs every X minutes and Y seconds ) that connects to an external service and gets the RAW data and send it to python.
I can rewrite everything in Python but that will take a me good amount of time. I was looking if there is a way to reuse what I already have.
I want to use an existing Python script with minimal change. My python script uses a bunch of external libraries (e.g., numpy)
The data passed from Java to Python is in Json format and the data returned by Python is also Json.
Using sockets is an options but then I've to run server processes.
I hacked this together a couple of months ago when I was faced with an similar problem. I avoided Jython because I wanted separate processes. The Java code is the server as it listens for requests but it doesn't re-connect on failure. The concept is is that the classes are extended threads that have a socket member so the send and receive commands can block the object threads and leave the host threads unaffected.
Python Code:
import StringIO
import re
import select
import socket
import sys
import threading
class IPC(threading.Thread):
def __init__(self, line_filter = None):
threading.Thread.__init__(self)
self.daemon = True
self.lock = threading.Lock()
self.event = threading.Event()
self.event.clear()
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.recv_buffer_size = 8192
self.buffer = StringIO.StringIO()
if(line_filter == None):
self.line_filter = lambda x: x
else:
self.line_filter = line_filter
def run(self):
self.sock.connect(("localhost", 32000))
data = True
while data:
try:
data = self.sock.recv(self.recv_buffer_size)
except socket.error, e:
print e
self.sock.close()
break
self.lock.acquire()
self.buffer.write(data)
self.lock.release()
self.event.set()
def readlines(self):
self.lock.acquire()
self.buffer.seek(0)
raw_lines = self.buffer.readlines()
self.buffer.truncate(0)
self.lock.release()
lines = map(self.line_filter, raw_lines)
return lines
proc_control = IPC()
while True:
proc_control.event.wait()
data = proc_control.readlines()
if(data):
# Do Stuff
proc_control.event.clear()
Java Code:
SocketIPC.java:
package project;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class SocketIPC {
public PrintWriter out;
public BufferedReader in;
Socket socket = null;
ServerSocket serverSocket = null;
ConnectionListener connlisten = null;
DataListener datalisten = null;
Thread connlisten_thread = null;
Thread datalisten_thread = null;
CommandObject ipc_event_cmd = null;
// Server thread accepts incoming client connections
class ConnectionListener extends Thread {
private int port;
ConnectionListener(int port) {
this.port = port;
}
#Override
public void run() {
try {
serverSocket = new ServerSocket(port);
socket = serverSocket.accept();
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
datalisten = new DataListener();
datalisten_thread = new Thread(datalisten);
datalisten_thread.start();
} catch (Exception e) {
System.err.println("SocketIPC creation error: " + e.getMessage());
}
}
}
// Server thread accepts incoming client connections
class DataListener extends Thread {
String data_str = null;
DataListener() {
}
#Override
public void run() {
try {
while(true) {
data_str = recv();
ipc_event_cmd.buffer.add(data_str);
ipc_event_cmd.execute();
}
} catch (Exception e) {
System.err.println("SocketIPC reading error: " + e.getMessage());
}
}
public String read() {
String ret_string = null;
if(!ipc_event_cmd.buffer.isEmpty()) {
ret_string = ipc_event_cmd.buffer.remove(0);
}
return ret_string;
}
}
public SocketIPC(int port) {
ipc_event_cmd = new CommandObject();
connlisten = new ConnectionListener(port);
connlisten_thread = new Thread(connlisten);
connlisten_thread.start();
}
public void send(String msg) {
if (out != null) {
out.println(msg);
}
}
public void flush() {
if (out != null) {
out.flush();
}
}
public void close() {
if (out != null) {
out.flush();
out.close();
try {
in.close();
socket.close();
serverSocket.close();
} catch (Exception e) {
System.err.println("SocketIPC closing error: " + e.getMessage());
}
}
}
public String recv() throws Exception {
if (in != null) {
return in.readLine();
} else {
return "";
}
}
public void set_cmd(CommandObject event_cmd) {
if (event_cmd != null) {
this.ipc_event_cmd = event_cmd;
}
}
}
CommandObject.java:
package project;
import java.util.List;
import java.util.ArrayList;
public class CommandObject {
List<String> buffer;
public CommandObject() {
this.buffer = new ArrayList<String>();
}
public void execute() {
}
}
DoStuff.java:
package project;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;
public class DoStuff extends CommandObject {
public DoStuff () {
}
#Override
public void execute() {
String tmp_string = null;
while (!buffer.isEmpty()) {
tmp_string = buffer.remove(0);
// Do Stuff
}
}
}
Sounds like a job for Jython! Jython is an embeddedable Python runtime written in Java. As long as you don't need to run your Python script in another process (e.g., want to be able to kill it, may use lots of memory, etc.), this is the best way by far.
If you are trying to work Java and python together then make your life simple with Jython.
Jython, successor of JPython, is an implementation of the Python
programming language written in Java. Jython programs can import and
use any Java class. Except for some standard modules, Jython programs
use Java classes instead of Python modules. Jython includes almost all
of the modules in the standard Python programming language
distribution, lacking only some of the modules implemented originally
in C.
Assuming you have java lib in your python path. Here is a code snippet to give you an idea how simple it is to use the java classes:
'''
Import JavaUtilities class from a java package
'''
from com.test.javalib import JavaUtilities
'''
Call a java method
'''
response = JavaUtilities.doSomething();
Please have a look Jython,which is best for communication between java and Python.
I was wondering if it is possible to check whether there is an instance of an object(my gui) open in Java and if so how I would be able to find it?
You can use following code if this question is for swing window like JFrame or JDialog,
java.awt.Window win[] = java.awt.Window.getWindows();
for(int i=0;i<win.length;i++){
if (win[i].getName().equals("YourWindowName"))
isOpen = true;
break;
}
For this ypu need to give name to your JFrame and if that matches with open windows it will set true and return.
I used RMI to solve the same problem. My application creates Registry and places a lock object there after start. If lock object is already there at that time then it sends message via RMI to existing application and terminates. The sent message triggers existing application to move its window on top. Here is the code
public static void main(String[] args) {
RmiManager rmiManager = new RmiManager();
rmiManager.createRmiRegistry();
if(rmiManager.isAlreadyRunning()) {
logger.error("Another application instance is running! Exit");
System.exit(0);
return;
}
rmiManager.registerApplication();
}
RmiManager.java which is actually responsible for all the stuff
package myapp;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.io.File;
import java.io.IOException;
import java.rmi.registry.LocateRegistry;
import java.rmi.NotBoundException;
import java.rmi.registry.Registry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import org.apache.log4j.Logger;
public class RmiManager {
private static final String LOCK_OBJECT_NAME = "myapp";
private static final Logger logger = Logger.getLogger(RmiManager.class);
public void createRmiRegistry() {
try {
logger.debug("Creating RMI registry...");
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
logger.debug("RMI registry was created");
} catch (RemoteException e) {
logger.debug("RMI registry is already created");
}
}
public boolean isAlreadyRunning() {
try {
logger.debug("Checking if application is already running. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry obtained. Looking for RmiListener: " + LOCK_OBJECT_NAME + "...");
try {
IRmiListener rmiListener = (IRmiListener) registry.lookup(LOCK_OBJECT_NAME);
logger.debug("RmiListener got. Checking...");
boolean isAlreadyRunning = rmiListener.isAlreadyRunning();
logger.debug("IsAlreadyRunning result: " + isAlreadyRunning);
return isAlreadyRunning;
} catch (AccessException e) {
logger.error("Error accessing RMI registry!", e);
return false;
} catch (NotBoundException e) {
logger.debug("RMI listener wasn't found. There are no other application instances running");
return false;
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
return false;
}
}
public void registerApplication() {
try {
logger.debug("Registering application...");
RmiListenerImpl rmiListenerImpl = new RmiListenerImpl();
logger.debug("Exporting RmiListener object...");
IRmiListener rmiListener = (IRmiListener) UnicastRemoteObject.exportObject(rmiListenerImpl, Registry.REGISTRY_PORT);
logger.debug("RmiListener object was exported. Looking for RMI registry...");
Registry registry = LocateRegistry.getRegistry();
logger.debug("RMI registry found");
try {
logger.debug("Binding RmiListener to " + LOCK_OBJECT_NAME + "...");
registry.bind(LOCK_OBJECT_NAME, rmiListener);
logger.debug("RmiListener binding was done. Application registration complete.");
} catch (AccessException e) {
logger.error("AccessException!", e);
} catch (AlreadyBoundException e) {
logger.error("RmiListener object is already bind", e);
}
} catch (RemoteException e) {
logger.error("RemoteException!", e);
}
}
}
IRmiListener.java
package myapp;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IRmiListener extends Remote {
boolean isAlreadyRunning() throws RemoteException;
}
RmiListenerImpl.java
package myapp;
import java.rmi.RemoteException;
import org.apache.log4j.Logger;
public class RmiListenerImpl implements IRmiListener {
private static final Logger logger = Logger.getLogger( RmiListenerImpl.class );
#Override
public boolean isAlreadyRunning() throws RemoteException {
// here I notify my GUI class to pop up the window
return true;
}
}
It can be more simple I think.
Assuming that by "open UI objects" you mean Swing dialogs and frames, it is better to design the application in a way that would remove the need to look for open instances all together.
This can be achieved by providing a factory that would produce application dialogs and frames instead of using something like new JFrame. This factory would register the produced instances internally and would serve as a single point of reference for all "open UI objects".
Although, be careful when implementing such solution as every registered object would have one additional reference preventing GC from collecting the allocated memory as intended. Please used weak references (weak reference map) for caching. A good blog post about different kinds of Java references can be found here.
This way if you need to find an open UI object, simply request your factory to provide a list of open instances.