在你说之前,是的,我知道,Stackoverflow上有很多线程可以解决同样的问题,但其中任何一个都解决了我的问题。我的问题是在两台不同的计算机上使用RMI接口(这对我来说是强制性的),其中一台提供RMI对象(服务器),另一台请求Stub并获得代理。我的代码是Oracle的Java 7参考手册提供的并由Oracle Press编辑的完整副本:
IRmi.java
import java.rmi.*;
public interface IRmi extends Remote {
double add() throws RemoteException;
}
RmiImpl.java
import java.rmi.*;
import java.rmi.server.*;
public class RmiImpl extends UnicastRemoteObject implements IRmi {
public RmiImpl() throws RemoteException {}
public double add() { double d = 5.0; return d; }
}
Server.java
import java.net.*;
import java.rmi.*;
public class Server {
public static void main(String s[]) {
try {
RmiImpl ri = new RmiImpl();
Naming.rebind("Server",ri);
} catch (Exception e) {
System.err.println("Err");
}
}
}
Client.java
import java.rmi.*;
public class Client {
public static void main(String s[]) {
try {
IRmi itf = (IRmi)Naming.lookup("rmi://192.168.0.8/Server");
System.out.println(itf.add());
} catch (Exception e) {
e.printStackTrace();
}
}
}
之后,我编译:
javac IRmi.java
javac RmiImpl.java
rmic RmiImpl
javac Client.java
javac Server.java
在那段话之后,我复制了客户端和服务器上的所有类,然后在转移类的同一文件夹上运行rmiregistry
。假设在我的本地局域网(192.168.0.0/255)中有两台机器,其中客户端是192.168.0.3,服务器192.168.0.8我分别在这些机器上运行java client
和java Server
,其中客户端返回以下错误:
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
java.net.ConnectException: Connessione rifiutata
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 RmiImpl_Stub.add(Unknown Source)
at Client.main(Client.java:8)
Caused by: java.net.ConnectException: Connessione rifiutata
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:147)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
例如,在另一个测试中,我也尝试使用以下代码实现服务器:
try {
RemImpl obj = new RemImpl(this.serv);
if (this.ob_list.size()>0) {
for (Observer ob: ob_list) {
obj.addObserver(ob);
}
}
this.myrec = (Rem) UnicastRemoteObject.exportObject(obj, 9999);
Registry registry = LocateRegistry.createRegistry(9999);
registry.rebind(this.serv, this.myrec);
//this.has_error = false;
System.out.println("Binded as "+this.serv);
} catch (RemoteException e) {
System.err.println("Remote exception catched: " + e.getMessage());
//this.has_error = true;
this.myrec = null;
}
和客户端使用以下其他代码:
try {
Registry registry = LocateRegistry.getRegistry(host);
this.myrec = (Rem) registry.lookup(service);
} catch (Exception e) {
e.printStackTrace();
}
并且,在这种情况下,客户端返回以下不同的错误:
java.rmi.NoSuchObjectException: no such object in table
ERROR
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:161)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.send(Unknown Source)
at rmi.lowlevel.NullSenderPolicy.send(NullSenderPolicy.java:81)
at message.policy.old.BroadcastSenderPolicy.single_send(BroadcastSenderPolicy.java:104)
at message.policy.old.AtomicBroadcastSender.fifo_send(AtomicBroadcastSender.java:54)
at message.policy.old.AtomicBroadcastNode.fifo_send(AtomicBroadcastNode.java:131)
at elements.testunit.TestPairBroadcastNodes.main(TestPairBroadcastNodes.java:20)
此时我不知道转向哪个方向。提前感谢任何其他建议。
答案 0 :(得分:1)
连接拒绝似乎是item A.1 in the RMI FAQ的情况。
NoSuchObjectInTable问题是因为你正在查找错误的注册表。您在端口9999上创建了它,但是您正在查找另一个。这可以通过在客户端调用getRegistry(serverHost,9999)来解决。
您还应该在服务器JVM中使注册表引用为静态。
答案 1 :(得分:1)
实际上,最近通过在客户端和服务器上添加-Djava.rmi.server.hostname=192.168.0.x
参数来解决问题。感谢您的所有建议。