I propose a solution based on a customized RMISocketFactory.
As explained on the Sun Site, you can provide your own SocketFactory: http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/socketfactory/
My solution uses this mecanism to create a client socket interception and replace the received host (127.0.0.1) with a good IP, a well-known client.
The rest of the communication mechanism is still based on java rmi standards.
In this implementation, the exporter does not need to know its own IP address, which is sometimes not easy (several network interfaces ...)
Here are the tree classes, Factory, server and client. The Hello class and interface are also loaded to be comprehensive.
Hope this should be disposed of.
SocketFactory:
import java.io.IOException; import java.io.Serializable; import java.net.ServerSocket; import java.net.Socket; import java.rmi.server.RMISocketFactory; public class MySocketFactory extends RMISocketFactory implements Serializable { private static String server = "localhost"; @Override public Socket createSocket(String host, int port) throws IOException { System.out.println("change host from " + host + " to " + server); return getFactory().createSocket(server, port); } @Override public ServerSocket createServerSocket(int port) throws IOException { return getFactory().createServerSocket(port); } private RMISocketFactory getFactory() { return RMISocketFactory.getDefaultSocketFactory(); } public static void setServer(String host) { server = host; } }
Exporter:
import java.io.IOException; import java.rmi.Naming; import java.rmi.RMISecurityManager; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.RMISocketFactory; import java.rmi.server.UnicastRemoteObject; public class MyRmiExporter { public static void main(String[] args) throws RemoteException, IOException { System.setSecurityManager(new RMISecurityManager()); Hello export = new HelloImpl(); RMISocketFactory sf = new MySocketFactory(); UnicastRemoteObject.unexportObject(export, true); Remote stub = UnicastRemoteObject.exportObject(export, 0, sf, sf); String url = "rmi://0.0.0.0:" + Registry.REGISTRY_PORT + "/Hello"; LocateRegistry.createRegistry(Registry.REGISTRY_PORT); Naming.rebind(url, stub); System.out.println("Exported " + url); } }
Client:
import java.io.IOException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.registry.Registry; public class MyClient { public static void main(String[] args) throws IOException, NotBoundException, InterruptedException { String host = args[0]; MySocketFactory.setServer(host); String url = "rmi://" + host + ":" + Registry.REGISTRY_PORT + "/Hello";; System.out.println("look up " + url); Hello proxy = (Hello) Naming.lookup(url); System.out.println("OK, remote getted !"); System.out.println(proxy.hello("bonjour")); } }
Bean:
import java.io.Serializable; import java.rmi.Remote; import java.rmi.RemoteException; public interface Hello extends Remote, Serializable { String hello(String mess) throws RemoteException; }
Impl:
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class HelloImpl extends UnicastRemoteObject implements Hello { public HelloImpl() throws RemoteException { } @Override public String hello(String mess) throws RemoteException { return "hello : " + mess; } }
last and smallest, java.policy:
grant { permission java.security.AllPermission; };