另一个RMI问题

时间:2013-11-22 20:11:13

标签: java rmi java-7 javac

在你说之前,是的,我知道,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 clientjava 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)

此时我不知道转向哪个方向。提前感谢任何其他建议。

2 个答案:

答案 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参数来解决问题。感谢您的所有建议。