gpt4 book ai didi

java - Java RMI 回调在表异常中没有这样的对象

转载 作者:行者123 更新时间:2023-11-30 08:12:07 25 4
gpt4 key购买 nike

我正在尝试使用 RMI 在 Java 中使用回调。

我有一台在 AWS 上运行的服务器。我的客户端成功连接到服务器并注册了回调。但是,在尝试调用它时,服务器端出现以下异常:

java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:276)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:253)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:162)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy3.call(Unknown Source)
at server.SimpleUpdateManager.callAll(SimpleUpdateManager.java:42)
at server.Server$1.run(Server.java:77)
at java.lang.Thread.run(Thread.java:745)

我不知道为什么会这样。我已经检查过 rc(客户端上的 RemoteCallback 实现实例)没有被垃圾回收。您知道为什么它可能不起作用吗?

这是我的远程接口(interface):

public interface RemoteCallback extends Remote {
void call() throws RemoteException;
}

public interface CallbackManager extends Remote{
void register(RemoteCallback uc) throws RemoteException;
void unregister(RemoteCallback uc) throws RemoteException;
void callAll() throws RemoteException;
}

相关服务器代码:

 public class SimpleUpdateManager implements CallbackManager {

private HashSet<RemoteCallback> callbacks;

public SimpleUpdateManager() {
callbacks = new HashSet<>();
}

@Override
public synchronized void register(RemoteCallback uc) {
callbacks.add(uc);
System.out.println("Callback registered");
}

@Override
public synchronized void unregister(RemoteCallback uc) {
callbacks.remove(uc);
}

@Override
public synchronized void callAll() {

ArrayList<RemoteCallback> toDelete = new ArrayList<>();

for(RemoteCallback rc : callbacks) {
try {
rc.call();
System.out.println(" Called one listener");
} catch (RemoteException re) {
re.printStackTrace();
toDelete.add(rc);
}
}

for(RemoteCallback rc :toDelete)
unregister(rc);

System.out.println("Called all listeners");
}
}

服务器类的摘录:

private static SimpleUpdateManager setupUpdateManager() {
String name = "UpdateManager";
SimpleUpdateManager sum = new SimpleUpdateManager();

try {
CallbackManager exp = (CallbackManager) UnicastRemoteObject.exportObject(sum, 1100);
LocateRegistry.getRegistry().rebind(name, exp);
}
catch(RemoteException re) {
System.out.println("Setting up update manager failed");
re.printStackTrace();
}
return sum;
}

public static void runUpdateDaemon(SimpleUpdateManager sum) {

Thread updateDaemon = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
System.out.println("I will try calling all listeners");
sum.callAll();
TimeUnit.SECONDS.sleep(5);
}
catch (InterruptedException ie) {
break;
}
}
}
});
//updateDaemon.setDaemon(true);
updateDaemon.start();
}

和客户端代码:RemoteCallback 实现

public class SimpleCallback  implements RemoteCallback {
@Override
public void call() throws RemoteException {
System.out.println("Callback called");
}

@Override
protected void finalize() {
System.out.println("Callback gc'd");
}
}

和回调的注册

try {
rc = new SimpleCallback();
UnicastRemoteObject.exportObject(rc, 1100);
((CallbackManager) LocateRegistry.getRegistry(host).lookup("UpdateManager")).register(rc);
System.out.println("Callback registered");
}
catch (RemoteException|NotBoundException re) {
System.out.println("Cannot register callback");
re.printStackTrace();
}

最佳答案

问题是这样的:

客户端位于不允许从服务器访问端口 1100 的防火墙后面,因此 DGC 假定客户端已崩溃并以某种方式垃圾收集了回调。

关于java - Java RMI 回调在表异常中没有这样的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30692235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com