Let's revisit RMI a little.
On the server side:
Your RemoteServicesImpl implements the Services interface either directly or through a helper
. RMI provides a server side proxy (stub) that also implements the Services interface and delegates to the RemoteServicesImpl instance that you bound to the RMI registry. All communication via RMI from the client side goes through this proxy.
On the client side:
RMI provides a proxy against which you can make your Services method calls. This object is created by RMI is neither a RemoteServicesImpl or a Data object. The proxy object RMI provides can only be cast to Services. All communication via RMI to the server side goes through this proxy.
I leave it to you to figure out the rest. I don't want to spoil your fun.
FYI: You cannot use the following for the cert, but it can be useful afterwards.
Spring provides a nice Remoting technology that is a simple alternative to RMI called HttpInvoker. Essentially it provides Remoting via Java serialization over HTTP. Unlike RMI, it does not need a central registry, it only needs an HTTP port to serve. Another real plus for this is that since runs over HTTP, it is very firewall friendly, unlike RMI. This strategy, of course, only is useful when both the client and server are implemented using Java and Spring. You only need to write your service interface and its implementation as POJO's that have no knowledge whatsoever of any Remoting that is going on and don't have to handle any checked Exceptions.
Spring also maps RemoteExceptions to unchecked RemoteAccessExceptions making your code much easier to write. In fact it does this exception mapping for a number of other Remoting technologies as well as HttpInvoker.
Switching Remoting strategies is often as simple as tweaking 2 simple XML configurations, 1 on the server and 1 on the client.