- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
已经有几个与此相关的问题,但他们的答案表明导出的对象已在服务器端进行 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 7something 的同一台机器上。
根据其他答案,我应该保留对处理对象的强引用。我现在就在做,还能做什么呢?
相同的代码可以在 Windows 上运行,也可以在装有 java 7 的不同远程 Linux 机器上运行。有什么想法吗?
我已经为连接的类实现了一些终结器,但没有一个被调用。
正如建议的那样,我正在使用静态引用。对于我来说,没有办法让导出的对象 GC 合格。 对象查找后立即调用远程方法会引发异常。
类(class)的一部分
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
这会等到手动关闭 - 经过测试。
最佳答案
NoSuchObjectException
Javadoc :
A NoSuchObjectException is thrown if an attempt is made to invoke a method on an object that no longer exists in the remote virtual machine.
这意味着您正在调用方法的 stub 所引用的远程对象尚未导出,即 stub 已“过时”。发生这种情况的唯一方法是手动或通过 GC 取消导出对象。
As suggested I am using static references.
不,你不是。您需要将 Registry
引用设为静态。否则,您只是在 Client
和 Registry
之间形成一个可以一次性进行垃圾收集的循环。
为什么要调用服务器 Client
是另一个谜。
编辑一些评论:
stub = UnicastRemoteObject.exportObject(searchTestService, RMI_PORT + 1);
此处无需使用第二个端口。只需重新使用注册表端口即可。
log.info("Binding {} to port {}", SearchTestService.class.getName(), RMI_PORT + 1);
这是误导性的。您已经完成了这两件事,但您所做的是:
分两个单独的步骤。
System.gc();
System.runFinalization();
在这里,甚至在任何地方,都会发生奇怪的事情。
synchronized (c) {
c.wait();
}
这不可靠。这里您实际上不需要任何东西,因为只要 JVM 导出了远程对象,RMI 就应该保持 JVM 打开,但您可以执行注册表所做的操作:
while (true)
{
Thread.sleep(Integer.MAX_VALUE);
}
具有适当的异常处理。
我无法重现您的问题,但我使用的是 Windows 7。
关于java.rmi.NoSuchObjectException : no such object exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30593765/
当我启动 spark 时,我收到以下警告: Using Scala version 2.10.5 (OpenJDK 64-Bit Server VM, Java 1.8.0_77) Type in e
我尝试设置一个简单的 RMI 实现,但遇到了一些麻烦。 服务器启动正常,但客户端似乎永远找不到远程对象(Naming.lookup 每次都失败)。通过阅读周围的内容,人们提到将远程对象(Bank)存储
我有一个使用 Java RMI 的服务器和客户端。如果我使用一个客户端,下面的代码一切都很好。但是,如果我连接一个客户端,然后连接第二个客户端,它会抛出端口已在使用异常。没关系,所以我断开连接的客户端
我正在使用java RMI实现客户端/服务器应用程序,客户端和服务器位于同一项目中的不同包中(当然它们在同一台机器上运行),并且接口(interface)在“通用”包中定义。当我尝试获取两个远程对象之
已经有几个与此相关的问题,但他们的答案表明导出的对象已在服务器端进行 GC,这解决了问题。然而,这似乎不是这里的问题。 提到的异常仅在单台机器上抛出: PRETTY_NAME="Debian GNU/
我在 Weblogic 11g 上运行 Java 6。 我正在开发一个使用 EJB 与数据库通信的 Web 服务项目。目前我正在处理错误,因此我尝试在调用 Web 服务之前取消部署 EJB。我的 EJ
我正在开发两个通过 RMI 连接的应用程序。通信是双向的,一切正常,直到我在 Windows 上运行。当我将 jar 文件传输到 Debian 时,连接失败并显示 java.rmi.NoSuchObj
我正在编写一个非常简单的 RMI 服务器,我在单元测试中看到间歇性的 java.rmi.NoSuchObjectExceptions。 我在同一个对象上有一串远程方法调用,虽然前几个通过,但后面的有时
我有一个简单的程序,可以使 calcPi() 通过 Java-RMI 可用,当我启动程序时,我收到此异常: java.rmi.NoSuchObjectException: no such object
这是我的应用程序在更改之前的代码: Static Map servStubs = Collections.synchronizedMap(new HashMap); public synchroni
我是一名优秀的程序员,十分优秀!