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



我有一个服务器和一个客户端通过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:沙箱。CImpl

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

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

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

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

UnicastRemoteObject.unexportObject(refToC, true);

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

java.rmi.ServerException:服务器线程中发生RemoteException;嵌套异常为:java.rmi.NoSuchObjectException:对象不是出口

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

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

共享对象是UnicastRemoteObject

不是。再看一遍:

public class CImpl implements CInterface

添加extends UnicastRemoteObject,并提供一个合适的构造函数,您的问题就会消失。

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

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

相关内容

  • 没有找到相关文章

最新更新