Java RMI 在没有绑定(bind)的情况下返回对远程对象的引用

标签 java rmi remoteobject rmiregistry

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

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

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

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

这是共享对象接口(interface)

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: error unmarshalling return; nested exception is: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: sandbox.CImpl

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

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

我不明白的是为什么我需要再次通过注册表,虽然没有显式绑定(bind)名称,只是为了返回一个远程引用。客户端之前使用 rmiregistry 获得了对服务器的引用,因此 Bootstrap 已完成。现在,为什么服务器不能在不知道 rmiregistry (1099) 端口的情况下直接返回对客户端的引用?

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

UnicastRemoteObject.unexportObject(refToC, true);

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

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.NoSuchObjectException: object not exported

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

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

最佳答案

The shared object is a UnicastRemoteObject

不,不是。再看一遍:

public class CImpl implements CInterface

向其添加extends UnicastRemoteObject,并提供适当的构造函数,您的问题就会消失。

您不需要调用 exportObject(),也不需要第二次绑定(bind)到注册表。

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

关于Java RMI 在没有绑定(bind)的情况下返回对远程对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20827403/

相关文章:

linux - JMeter远程测试,测试结果不显示

JAVA RMI,定义离线方法,所以当方法调用时不会去服务器

java - RMI 远程对象到 stub

java - Spring中的刷新属性占位符机制

java.lang.ClassCastException : [Ljava. lang.Comparable;不能转换到

java - 在 Java 中伪造堆栈跟踪

java - 从数据库填充 JavaFX 中的组合框

java - 无法映射第二类 : ** org. hibernate.MappingException:表员工中的关联引用了未映射的类**

java - Playframework 2.x Apache Tika 问题

java - 从服务器编码 RMI 客户端回调时遇到问题 - UnmarshalException ClassNotFoundException