Search code examples
javaooprmiabstractionleaky-abstraction

Design issue: RMI needs explicit exporting of objects


I have two applications communicating via RMI, a slave server (of which there will be multiple) and a master server.

Following good abstract design, I'd like to implement the slave in a way that it doesn't know that when talking to the master, it's using RMI (so that the two apps can also be run inside the same JVM, for instance):

public static void main(String[] a) {
     Master ms = magicGetTheMasterFromRMI();
     new Slave(ms);
}

...

class Slave {

   public Slave(Master m) {
       m.registerSlave(this); // PROBLEM LINE   
   }

}

Problem: The line marked PROBLEM LINE above doesn't work, because I cannot simply pass this (the Slave itself is a Remote which Master will talk back to). I have to explicitly do a UnicastRemoteObject.exportObject(this, 0) (or toStub(this) if it's exported earlier) but that makes the Slave class depend on RMI, breaking the design.

Additionally, registerSlave forces me to catch RemoteException, which also adds RMI dependency.

What would you suggest to solve these issues?

(It also bugs me that these classes must implement Remote, but I guess we can only go so far with abstraction)


Solution

  • Well, I've done it like this:

    interface Service {
       void doIt();
    }
    
    class ServiceImpl implements Service {
      public void doIt() { ... }
    }
    
    interface RemoteService extends Remote {
      void proxyDoIt() throws RemoteException;
    }
    
    class RemoteServiceHost implements RemoteService {
      public void proxyDoIt() throws RemoteException {
        // serviceImpl is a field, defined in the constructor
        serviceImpl.doIt();
      }
    }
    
    class RemoteServiceClient implements Service {
      public void doIt() {
       try {
        // remoteService is a field, defined in the constructor
        remoteService.proxyDoIt();
       } catch (RemoteException e) {
        throw new RuntimeException(e);
       }
      }
    }