Search code examples
javacallbackrmi

Java RMI Exception creating connection when used on != machines


I've been struggling with a RMI problem for a couple of hours now. Its a pretty stupid example for now that only works when I launch the both the client & server on the same computer. As soon as I launch the client ^ server on a != machine, i get an exception when the server tries to call the callback :

Exception creating connection to: 192.168.244.1; nested exception is: 
java.net.SocketException: Network is unreachable
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:632)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:128)

Which by the way does not make any sense since i'm on a 10.0.0.x subnet, where does this IP comes from ?

The code is composed of two classes, Server & Client, implementing two {Server|Client}Interfaces. I have no problem getting the server object from the RMIRegistry, and calling the login method. I can see with a breakpoint in the server side that the code is executed, however as soon as it comes to the callback instruction it fails. The exception is client-side btw.

I tried disabling firewall on both machines with no success. I suspect that the problem comes from the ip the exception sends me, but I can't figure out where does it comes from.

Here is the following code : (Client.java)

public class Client extends UnicastRemoteObject implements ClientInterface {

    public static void main(String[] args) {
        try {
            new Client();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
    }

    public Client() throws RemoteException, MalformedURLException, NotBoundException {
        ServerInterface s = null;
        s = (ServerInterface) Naming.lookup("rmi://10.0.0.48/server");
        s.login(this);
    }

    @Override
    public void talk() throws RemoteException {
        System.out.println("Talkiiiing");
    }
}

(ClientInterface.java)

public interface ClientInterface extends Remote {
    void talk() throws RemoteException;;
}

(Server.java)

public class Server extends UnicastRemoteObject implements ServerInterface {

    public Server() throws RemoteException, MalformedURLException {
        LocateRegistry.createRegistry(1099);
        if (System.getSecurityManager() == null)
            System.setSecurityManager(new RMISecurityManager());
        Naming.rebind("rmi://localhost:1099/server", this);
    }

    public static void main(String[] args) {
        try {
            new Server();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void login(ClientInterface clientInterface) throws RemoteException {
        clientInterface.talk();
    }
}

And finally the (ServerInterface.java)

public interface ServerInterface extends Remote {
    void login(ClientInterface clientInterface)  throws RemoteException;
}

Solution

  • This is the classic java.rmi.server.hostname problem. See item A.1 in the RMI FAQ. You need to set java.rmi.server.hostname at the server JVM to the address you want your clients to use when connecting. The problem is caused by a misconfigured DNS: maybe you can fix it there instead: better if you can. 'localhost' should resolve to 127.0.0.1 and your hostname should resolve to your real IP address.