Java – NotBoundException on localhost

javarmi

I have a RMI server running on the localhost, exporting an object of type Message:

try {
    MessageServer obj = new MessageServer();
    Message stub = (Message) UnicastRemoteObject.exportObject(obj, 0);
    Registry registry = LocateRegistry.getRegistry();
    registry.bind("M", stub);
} catch (RemoteException e) {
} catch (AlreadyBoundException e) {
}

Then I want to start a client and get the stub for this object. It seems that the registry is found but then in the try block a NotBoundException is thrown:

java.rmi.NotBoundException: M
at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136)
at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at rmitest.MessageClient.main(MessageClient.java:23)

public static void main(String args[]) {
        //String host = "localhost";
        Registry registry;
        Message stub = null;
        try {
            registry = LocateRegistry.getRegistry();
            stub = (Message) registry.lookup("M"); //NotBoundException thrown here
        } catch (NotBoundException ex) {
        } catch (AccessException ex) {
        } catch (RemoteException ex) {
        }
        try {
            stub.insert("TestString"); //NullPointerException here
        } catch (RemoteException ex) {
        }

}

Why is "M" not found? Both server and client are started inside Netbeans, the registry is started via terminal beforehand.

Best Answer

RMI is sort of a beast, it's always an issue how to run it.

First of all, do proper exception handling as @EJP suggested: a reason might be you get a connection timeout or something similar - so put an e.printStackTrace() into the catch blocks and let's see if we get sort of an error message (btw you gonna stop creating empty catch blocks really quickly when you debug a suppressed exception for 2 days). Can't it be your firewall that catches the connection?

I would also change getRegistry() to createRegistry(), and bind() to rebind() (it can save you a bit of time).

The exception you're getting is because your main application wasn't able to bind (register) the service you wanted, and it is missing (unavailable) from the default registry.

RMI can be done several ways. The approach you chose is absolutely cool for development and in testing, but you'll need to do some changes if you want to put it under production (e.g., probably there will be a common rmiregistry running somewhere, you'll have to use a policy file and some properties like java.rmi.codebase=..., you'll need a proper security manager installed, etc.)

Related Topic