我有一个java rmi应用程序,我只是这样做:
客户端:
Registry registry = LocateRegistry.getRegistry("localhost");
costApi = (CostApi) registry.lookup("server.CostApi");
当我在localhost上托管服务器时,一切正常。当我在另一台具有本地网络的计算机上启动相同的程序时,在192.168.x.x并更改为:
客户端:
Registry registry = LocateRegistry.getRegistry("192.168.x.x");
costApi = (CostApi) registry.lookup("server.CostApi");
它不再起作用,它失败并出现一个非常奇怪的错误:
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.dataCost(Unknown Source)
at billing.data.DataBiller.performBilling(DataBiller.java:57)
at billing.data.DataBiller.consumeMessage(DataBiller.java:46)
at general.templates.RabbitWorker.run(RabbitWorker.java:124)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
我甚至没有尝试连接到127.0.1.1但是连接到192.168.x.x,我该如何解决?我更喜欢只使用java代码而不是用配置文件修改我的机器。我正在使用linux
答案 0 :(得分:8)
这通常是由于配置错误造成的。检查您的/etc/hosts
文件以确保:
众所周知,有些Linux发行版会将这一点发布到前面。
如果问题仍然存在,请尝试将服务器上的java.rmi.server.hostname
设置为客户端在执行远程方法调用时应使用的IP地址。在导出任何远程对象(包括注册表)之前,需要先设置它。
问题是由存根中嵌入的IP地址引起的,最终来自InetAddress.getLocalAddress(),
之类的内容,如上所述。它被java.rmi.server.hostname.
这是item A.1 in the FMI FAQ,但请注意该项目是错误的。在lookup()
期间不会发生这种情况,当您在结果存根上调用远程方法时会发生这种情况。
答案 1 :(得分:2)
我刚遇到同样的问题。我正在做一些与你正在做的非常相似的事情。我注意到的是,我第一次运行客户端程序,它失败了(通过防火墙测试设计) - 它失败了,显示我最初指定的主机的实际IP地址的错误消息(192.168.xx)地址),但所有后续故障都表明它无法建立到127.0.0.1的连接。目前我怀疑在客户端上进行某种缓存 - JVM是否将该IP地址标记为永远无法访问,并且拒绝再次尝试连接到它?
更新:就我而言,RMI Server端的JVM无法在JVM启动时正确设置java.rmi.server.hostname属性。此属性保留为null。当客户端连接到特定的RMI注册表并要求存根到特定的命名对象时,它们会收到一个存根,其中包含可以找到实际对象的远程计算机的IP地址。 RMI服务器将java.rmi.server.hostname属性的内容复制到它返回给客户端的存根中,因此如果java.rmi.server.hostname属性为“”并将其复制到它创建的每个存根,则每个存根包含对IP地址为“”的远程服务器的引用。默认情况下,客户端jvm通过尝试连接到localhost,127.0.0.1上的服务器对象来对此作出反应。要解决此问题,请在导出服务器端的任何远程对象之前尝试以下代码:
System.setProperty( "java.rmi.server.hostname", "192.168.RMIServer.IP" ) ;
此属性将自动复制到该服务器上导出的所有远程存根,接收该存根的客户端应该能够访问远程服务器(假设任何防火墙配置正确)。