Search code examples
javaarchitecturermi

RMI: Does the client have to have all implementations or just interfaces?


Does client have to have all implementations or just interfaces?

In details: let we have remote interface Foo:

public interface Foo extends Remote {
    FooMessage getFooMessage () throws RemoteException;
    void setFooMessage (FooMessage fm) throws RemoteException;
}

Communication between client and server is happening by means of FooMessage.

public interface FooMessage {
    String getMsg ();
    void setMsg (String str);  
}

The client is very simple:

public void clientCode () {
    Foo foo = (Foo)Naming.lookup ("rmi://localhost/FooService");
    FooMessage msg = foo.getFooMessage ();
    msg.setMsg ("asdf");
    foo.setFooMessage (msg);
}

Both Foo and FooMessage should have concrete implementations on server side. The question is: should client have these implementations too or RMI mechanism transfers implementations implicitly?


Solution

  • The concrete implementation class can be loaded by the client from the server, using an RMI class loader. However, there are a common "gotchas" to keep in mind:

    1. The RMI class loader is disabled unless the client has a SecurityManager installed. This is intended to restrict the actions of any malicious code served to the client.
    2. The server needs to specify a "codebase" that is accessible to the client. This could be a file: URL on a shared file system, an http: server, etc. This is specified with the java.rmi.server.codebase system property.

    (Also note: the linked guide is useful, but it talks a lot about "stubs"; since Java 5, it is most common to use stubs generated dynamically at runtime by the client. The mechanism applies to any other classes that need to be shared, however.)