1
votes

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.

1
You will never find out until you write some proper exception handling.user207421
How do you mean that? I catch all possible exceptions and when debugging only the exception with the shown message is thrown at the position marked in the code.user905686
I mean that the code you posted ignores all exceptions. I include the server code, which has clearly thrown some exception preventing the bind() from executing. If you have other code, post that code, not this code.user207421
You are right, there indeed was a RemoteException on bind(). I thought the debugger jumped to a catch when stepping over a line that throws an exception... However, using createRegistry() solved the problem.user905686

1 Answers

2
votes

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.)