【发布时间】:2015-08-16 02:36:49
【问题描述】:
已经有一些关于这个的问题,但他们的回答表明导出的对象已经在服务器端进行了 GC,这会导致问题。然而,这似乎不是这里的问题。
提到的异常只在单机上抛出:
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
用java:
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
这也发生在与 OpenJDK 7 相同的机器上。
根据其他答案,我应该对处理对象保持强烈的参考。我现在正在做,还有什么可以做的?
相同的代码可以在 Windows 以及其他带有 java 7 的远程 linux 机器上运行。 任何想法为什么?
我已经为连接的类实现了一些终结器,但没有一个被调用。
正如建议的那样,我正在使用静态引用。至于我,没有办法让导出的对象 GC 合格。 在对象查找后立即在远程方法调用上引发异常。
类的片段
public class Client{
//some fields
private final int RMI_PORT;
private static SearchTestServiceImpl searchTestService;
private static Remote stub;
private Registry registry;
//and starting service
public void startService() throws RemoteException {
createRegistry();
searchTestService = new SearchTestServiceImpl(name);
stub = UnicastRemoteObject.exportObject(searchTestService, RMI_PORT + 1);
registry.rebind(SearchTestService.class.getName(), stub);
log.info("Binding {} to port {}", SearchTestService.class.getName(), RMI_PORT + 1);
}
private void createRegistry() throws RemoteException {
log.info("Starting RMI registry on port {}", RMI_PORT);
registry = LocateRegistry.createRegistry(RMI_PORT);
}
(...)
}
以及引导代码
public class Bootstrap {
private Logger log = LoggerFactory.getLogger(Bootstrap.class);
private static Client c;
public static void main(String[] args) throws NumberFormatException,
// some preparations
c = new Client(Integer.valueOf(port), name);
c.startService();
System.gc();
System.runFinalization();
synchronized (c) {
c.wait();
}
}
}
和堆栈跟踪
java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) ~[na:1.7.0_65]
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) ~[na:1.7.0_65]
at sun.rmi.server.UnicastRef.invoke(Unknown Source) ~[na:1.7.0_65]
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) ~[na:1.7.0_65]
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) ~[na:1.7.0_65]
at com.sun.proxy.$Proxy0.getName(Unknown Source) ~[na:na]
at call to a method of remote lookedup object #getName in this example.
请求的代码段 - 查找和调用抛出异常
//somewhere
SearchTestService c = getClient(address); // this returns nice stub
String name = c.getName(); // this is throwing exception
private SearchTestService getClient(String string) throws NumberFormatException, RemoteException, NotBoundException {
String[] parts = string.split(":");
Registry registry = LocateRegistry.getRegistry(parts[0], Integer.parseInt(parts[1]));
SearchTestService client = (SearchTestService) registry.lookup(SearchTestService.class.getName());
return (SearchTestService) client;
}
运行“监听”客户端代码(使用 RMI 注册表)后的控制台输出
10:17:55.915 [main] INFO pl.breeze.searchtest.client.Client - Starting RMI registry on port 12097
10:17:55.936 [main] INFO p.b.s.client.SearchTestServiceImpl - Test agent Breeze Dev staging is up and running
10:17:55.952 [main] INFO pl.breeze.searchtest.client.Client - Binding pl.choina.searchtest.remote.SearchTestService to port 12098
这会等到手动关机 - 测试过。
【问题讨论】:
-
您的服务器是否从数据库中获取某些内容并将其返回给客户端?我认为这可能是错误的意思是“表中没有这样的对象”
-
@BilboBaggins 不,这里没有 DAO
-
@shekharsuman
SearchTestService.class是一个interface extends Remote。我将在帖子中添加查找代码,但请记住,它在 4 台计算机上运行良好,但在其中一台计算机上抛出异常。 -
@Antoniossss-你能分享一下你的远程接口的代码
SearchTestService吗?而且,正如 EJP 所说,在您的类 Client 中将private Registry registry;设为静态!另外,请在SearchTestService c = getClient(address);! 中显示您作为 address 传递的内容 -
地址是一个 ip:port 字符串。明天贴界面代码。但是我不认为这是相关的。再次。此代码适用于本地和网络上的多台机器。但是仅在其中一个上引发异常