你知道为什么当我试图从Windows调用Unix机器上的方法时会得到RemoteException吗?
我在网络中,我不认为这是因为防火墙的问题,因为在Unix机器上启动RMI服务器后,我可以从Windows到unix机器进行"telnet“。我也不明白为什么要转到本地环回IP?
堆栈跟踪:
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在此之前,非常感谢您。
发布于 2010-05-01 12:26:03
您可能没有在Linux机器上正确配置您的主机名。我敢打赌,如果你在Linux机器上使用ping $(hostname)命令,它会ping通127.0.0.1。通常,这是由于/etc/hosts文件中的条目造成的。
有几种方法可以解决这个问题。最困难的方法是让你的Linux机器将它自己的主机名正确地解析为它的IP地址。你可以编辑你的/etc/hosts文件,设置你的DNS服务器,做任何你需要做的事情。挑战在于,虽然这可能使事情在技术上更正确,但您面临着破坏依赖于旧行为的东西的风险。
更改最少的路径是将set the system property java.rmi.server.hostname设置为您的Linux机器的主机名或IP地址。(即java -Djava.rmi.server.hostname=$(hostname) ...)。
为什么?
Java RMI注册服务器实际上是一个网络范围的注册服务器。其他机器上的对象可以将自己绑定到此注册表。
注册远程对象时,注册将包括网络地址作为注册的一部分。默认情况下,它使用的地址是“本地主机的IP地址,格式为”点分“。”在您的设置中,此地址为127.0.0.1。
当您的Windows box联系注册服务以获取远程对象的地址时,它将返回127.0.0.1。然后,它尝试联系该地址上的远程对象。这就是它转到环回地址的原因。
发布于 2013-12-13 18:09:47
我建议一个基于定制RMISocketFactory的解决方案。
就像Sun站点上解释的那样,您可以提供自己的SocketFactory:http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/socketfactory/
我的解决方案使用此机制来拦截客户端套接字的创建,并将接收到的主机(127.0.0.1)替换为客户端所熟知的良好IP。
通信机制的其余部分仍然基于java rmi标准。
使用这种实现,导出器不必知道它自己的IP,这有时并不容易(多个网络接口...)
下面是树型类、工厂、服务器和客户端。上载的Hello类和接口也是详尽的。
希望它是有用的
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's 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;
}
}导出器:
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);
}
}客户端:
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;
}实施:
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;
}
}最后也是最不重要的,java.policy:
grant {
permission java.security.AllPermission;
};https://stackoverflow.com/questions/2748259
复制相似问题