RMI RemoteException

Any idea why I get a RemoteException when trying to call methods on a Unix machine from Windows?
I am on the network and do not think that this is due to a problem with the firewall, since I can make "telnet" from a Windows window on Unix after starting the RMI server in a unix window. I also could not understand why this is happening with the local loop IP?

Stack trace:

RemoteException occured, details java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused: connect java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: java.net.ConnectException: Connection refused: connect 

Thank you very much in advance.

+6
java rmi
source share
2 answers

You probably have not configured your hostname on your Linux server correctly. I bet if you ping $(hostname) from your Linux box, it will be ping 127.0.0.1 . This usually happens due to an entry in your /etc/hosts .

There are several ways to solve the problem. The hard way would be to get your Linux server to correctly resolve its own hostname to its IP address. You can edit your /etc/hosts file, configure your DNS server, no matter what you do. The problem is that although this can make things more technically correct, you run the risk of breaking things that rely on old behavior.

The path of smallest change will set the system property java.rmi.server.hostname to the host name or IP address of your Linux package. (i.e. java -Djava.rmi.server.hostname=$(hostname) ... ).

Why?

The Java RMI Registration Server is actually an entire network registration server. Objects on other machines can bind to this registry.

When a remote entity is registered, registration includes a network address as part of the registration. By default, the address it uses is the β€œdot-square format” localhost IP address. In your setup, this address is 127.0.0.1 .

When your Windows window contacts the registration service for the address of the remote object, it returns 127.0.0.1 . He then tries to contact the remote object at this address. That's why it goes to loopback address.

+12
source share

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; /** * Socket Factory for RMI calls. * * This classe, instanciated from server when RMI objects are exported, is send * to the client who use it (transparently) for create sockets which call remote objects. * * This implementation give the ability to modify dynamically the target host cible. * * The host will not be aware of it own IP. */ public class MySocketFactory extends RMISocketFactory implements Serializable { /**Target host for RMI calls, setted by caller. */ private static String server = "localhost"; /** * Create a client socket, replacing required host by the host setted when the service is called, * via {@link #setServer(String)}. * The host received is usually 127.0.0.1, depending on property java.rmi.server.hostname on the exporter. */ @Override public Socket createSocket(String host, int port) throws IOException { System.out.println("change host from " + host + " to " + server); return getFactory().createSocket(server, port); } /** * Create a server socket. */ @Override public ServerSocket createServerSocket(int port) throws IOException { return getFactory().createServerSocket(port); } /** * Use default RMI factory. */ private RMISocketFactory getFactory() { return RMISocketFactory.getDefaultSocketFactory(); } /** * Save the target host. This method must be called before use of a service (before Naming.lookup). */ 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; /** * RmiExport */ public class MyRmiExporter { /** * java -Djava.security.policy=java.policy 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 { /** * java MyClient localhost */ 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; }; 
0
source share

All Articles