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)
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);
}
}
}