Java RMI返回对远程对象的引用而不进行绑定

时间:2013-12-29 16:32:24

标签: java rmi remoteobject rmiregistry

我有一台服务器和一台通过RMI进行通信的客户端。他们的目标是共享一个简单的对象,一起处理它,然后模拟服务器断开连接。

服务器的名称与rmiregistry绑定。客户端使用rmiregistry获取对服务器的远程引用。然后它使用此引用来调用一个方法,该方法返回对它们将共享的对象的引用。进一步的沟通将通过这个共享对象完成。

共享对象是UnicastRemoteObject,服务器拥有其实现,并且有一个方法返回对客户端的引用。

客户端知道共享对象的接口,从服务器获取远程引用,然后对其进行操作。请注意,服务器应返回远程引用,而不是序列化副本。

这是共享对象接口

public interface CInterface extends Remote {
    boolean testMethod() throws RemoteException;
}

这就是它的实现

public class CImpl implements CInterface {
    @Override
    public boolean testMethod() throws RemoteException {
        return false;
    }
}

这是服务器的方法,当客户端调用它时应返回远程引用

public CInterface exportRefToC() throws RemoteException {
    return new CImpl();
}

如果我从客户端调用它,它会给我这个例外

  

java.rmi.UnmarshalException:错误解组返回;嵌套   异常是:java.io.WriteAbortedException:写入中止;   java.io.NotSerializableException:sandbox.CImpl

如果我这样写的话,我可以让方法工作并返回一个远程引用

public CInterface exportRefToC() throws RemoteException {
    refToC = new CImpl();
    return (CInterface) UnicastRemoteObject.exportObject(refToC, 1099);
}

我没有得到的是为什么我需要再次浏览注册表,虽然没有明确地绑定名称,只是为了返回远程引用。客户端之前使用rmiregistry获得了对服务器的引用,因此引导程序已完成。现在,为什么服务器不能在不知道rmiregistry(1099)的端口的情况下返回对客户端的引用?

奖金问题,如果服务器想让它与客户端共享的对象不可用(模拟断开连接),那么有没有比这更好的方法

UnicastRemoteObject.unexportObject(refToC, true);

编辑:如果我在共享对象的实现中扩展UnicastRemoteObject,该方法的第一个版本可以工作,但是,devport不起作用并返回此异常

  

java.rmi.ServerException:服务器线程中发生了RemoteException;   嵌套异常是:java.rmi.NoSuchObjectException:object not   导出

EDIT2:再次检查,它确实有效,只需要在返回之前保存参考

public CInterface exportRefToC() throws RemoteException {
    refToC = new CImpl();
    return refToC;
}

1 个答案:

答案 0 :(得分:2)

  

共享对象是UnicastRemoteObject

不,不是。再看一下:

public class CImpl implements CInterface

为此添加extends UnicastRemoteObject,并提供相应的构造函数,您的问题就会消失。

您无需致电exportObject(),,也无需向注册管理机构提供第二次绑定。

你的上一个问题体现了一个错误。它应该是unexportObject(),,这是使对象不可用的正确方法。