Search code examples
javarmi

Remote Server doesn't response to client request - using Java RMI


I'm learning Java RMI so that i'm writing and testing this code, the problem here is that the client (notificationSink class) send a message and register itself with the server but the server (notificationSource class) doesn't do anything.

This is RemoteThingInterface that extends Remote class:

public interface RemoteThingInterface extends Remote{
    public void register(NotificationSink sink) throws RemoteException;
    public void notifySink(String text) throws RemoteException;    
}

This is NotificationSink class:

public class NotificationSink{
    private String name;
    private static String hostName = "Shine";
    private static int serverPort = 2712;
    private static String text = (new Date()).toString();

    public NotificationSink(String name){
        name = this.name;
    }

    public static void main(String [] args){
        RemoteThingInterface rmiserver;
        Registry reg;
        System.out.println("Sending "+text+" to "+hostName+" through port "+serverPort);

        try{
            reg = LocateRegistry.getRegistry(hostName, serverPort); 

            rmiserver = (RemoteThingInterface) reg.lookup("server");

            NotificationSink s = new NotificationSink("Eagle 1");

            rmiserver.register(s);

            rmiserver.notifySink(text);
        }catch(RemoteException ex){} catch (NotBoundException ex) {
            ex.printStackTrace();
        }
    }    
}

This is NotificationSource class:

public class NotificationSource extends UnicastRemoteObject implements RemoteThingInterface{
    private ArrayList sinks = new ArrayList<>();
    int port;
    Registry registry;

    public NotificationSource() throws RemoteException{
        try{
            port = 2712;
            registry = LocateRegistry.createRegistry(port);
            registry.rebind("server", this);
        }catch(RemoteException ex){
            ex.printStackTrace();
        }
    }

    @Override
    public void register(NotificationSink sink) {
        sinks.add(sink);
    }

    public ArrayList getSinks(){
        return sinks;
    }

    @Override
    public void notifySink(String text){        
        System.out.println("new sink registered, he is "+getSinks().get(0));
        System.out.println(text);
    }

    public static void main(String [] args){
        try{
            NotificationSource s = new NotificationSource();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

Please help to explain where i'm wrong and how to fix this. I tried to add some code to find the size of arraylist in server, it find out successfully, but other methods don't work .... codes are below:

adding this line to remotethinginterface: ArrayList getArray() throws RemoteException;

adding this line to notiSource:

@Override
    public ArrayList getArray() throws RemoteException {
        return sinks;
    }

adding this line to notiSink: System.out.println(rmiserver.getArray().size()); (before rmiserver.register()


Solution

  • the client (notificationSink class) send a message

    No it doesn't.

    and register itself with the server

    No it doesn't.

    but the server (notificationSource class) doesn't do anything.

    Why should it? There is no client request to do anything with. There can't be. It's impossible.

    catch(RemoteException ex){}
    

    The first major problem is here. You are ignoring RemoteException. Don't do that. Log it, print it, never ignore an exception unless you really know what you're doing. In this case you will therefore have ignored the nested NotSerializableException that was thrown when you called register().

    The second major problem is that NotificationSink needs to either:

    1. Implement Serializable, if you want it to execute at the server, or
    2. Implement a remote interface and extend UnicastRemoteObject, if you want it to execute at the client.