views:

202

answers:

2

Hey guys, I have an interesting one for you here!

I have one object, called Server, that implements two RMI interfaces, CSCP and ISCP. I need my Clients to be able to communicate on the RMI CSCP interface, but know nothing of the ISCP interface, and I need other servers to communicate with it on the ISCP interface but know nothing of the CSCP interface. With me so far?

Basically, at the moment I have it set up so that it binds twice, once to "ISCP" in the rmiregistry, and once to "CSCP".

However, when clients try to bind (bear in mind they only know the CSCP interface), they get an exception saying they cannot find the class ISCP - but they should have NO need for it.

So, how do have one object (Server) present two different RMI interfaces on two different rmibindings, keeping them separate?

You're a genius if you can solve this one for me :D If I wasn't clear enough let me know!

A: 

Try using Spring remoting and bind the same object under different names using different interfaces - it uses reflection to bind any Java object (i.e. does not need to implement Remote) and similarly to lookup and invoke methods.

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
  <property name="serviceName" value="ICSP"/>
  <property name="service" ref="myService"/>
  <property name="serviceInterface" value="example.ICSP"/>
</bean>

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
  <property name="serviceName" value="CSCP"/>
  <property name="service" ref="myService"/>
  <property name="serviceInterface" value="example.CSCP"/>
</bean>

These can be used programmatically using just the Spring libraries:

RmiServiceExporter e = new RmiServiceExporter();
e.setServiceName("SCSP");
e.setService(myServiceObj);
e.setServiceInterface(example.SCSP.class);
e.prepare(); // read the doc; I'm not sure this is the exact method
oxbow_lakes
Is there any way to do this in pure code? I don't get what this <bean> stuff is... We're not using an IDE or anything of any kind!
Ben
Well, if you have the Spring libraries, yes there is. The above is nothing to do with an IDE - it's just using the Spring XML configuration to describe a runtime-deployment (i.e. what to instantiate, how to wire collaborating instances etc). It's well worth getting familiar with. I'mm modify my answer though
oxbow_lakes
+1  A: 

I suggest write two adapter classes, once which implements ICSP, and one which implements CSCP. Each method in these adapter classes calls the appropriate method in the "real" object.

You then bind each of these adapter classes to RMI, under a different name, instead of binding the original object. Clients can retrieve whichever bound object they want, according to which interface they have.

Even if there only one interface, this would be good practise anyway, since it's usually a good idea to decouple your business objects from the remote transport mechanism they communicate with (RMI in this case). Having to export two remote interfaces makes this case even stronger.

skaffman