Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.rmi.NoSuchObjectException:没有这样的对象异常_Java_Rmi - Fatal编程技术网

java.rmi.NoSuchObjectException:没有这样的对象异常

java.rmi.NoSuchObjectException:没有这样的对象异常,java,rmi,Java,Rmi,关于这个问题已经有很多问题了,但是他们的回答表明导出的对象已经在服务器端进行了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 (bui

关于这个问题已经有很多问题了,但是他们的回答表明导出的对象已经在服务器端进行了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不受影响在对象查找之后立即在远程方法调用时引发异常。

一流的

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();
        }

    }
}
和stacktrace

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注册表)

这要等到手动停机测试

NoSuchObjectException
:

如果试图调用远程虚拟机中不再存在的对象上的方法,则会引发NoSuchObjectException

这意味着您正在调用方法的存根所引用的远程对象尚未被报告,即存根是“过时的”。唯一可能发生的方法是手动或作为GC的结果取消对象的移植

正如建议的那样,我使用的是静态引用

不,你不是。您需要将
注册表
引用设置为静态。否则,您只需在
客户机
注册表
之间形成一个循环,就可以一次性进行垃圾收集

为什么要调用服务器
客户端
是另一个谜

编辑一些评论:

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();
    }
    
    这是不可靠的。在这里,您实际上不需要任何东西,因为RMI应该保持JVM打开,只要它已导出远程对象,但您可以执行注册表所做的操作:

    while (true)
    {
        Thread.sleep(Integer.MAX_VALUE);
    }
    
    使用适当的异常处理


    我无法重现您的问题,但我现在使用的是Windows 7。

    您的服务器是否从数据库中获取某些内容并将其返回给客户端?我想这可能是因为错误意味着“表中没有这样的对象”@BilboBaggins不,没有DAOhere@shekharsuman
    SearchTestService.class
    是一个扩展了远程
    接口。我将在帖子中添加查找代码,但请记住,它在4台计算机上运行良好,但在一台计算机上引发异常。@Antoniossss请共享远程界面的代码
    SearchTestService
    ?而且,正如EJP所说的,创建
    私有注册表类客户端中的静态!另外,请在
    SearchTestService c=getClient(address)中显示您作为地址传递的内容!地址是ip:端口字符串。明天我将粘贴接口代码。然而,我不认为这是相关的。再一次。此代码适用于本地和网络上的多台计算机。但是,仅在其中一个主题上引发异常。对于mistery,这段代码将同时在多台计算机上启动,controller将远程调用客户端;)如果注册表是GCd,我就不能像现在一样查找,对吗?此外,这是我第一次执行这样的hax,我在RMI应用程序上做了十几个。还有一件事,这里没有字段是垃圾回收的,因为它强烈引用了
    客户机
    对象并在其上保持监视器。仅供参考,对
    注册表的静态引用
    没有改变任何内容。@shekharsuman您是否有疑问,或者您认为这是原因?反正-缺少包=没有编译的jar。这里根本不使用反射。@down如果你知道一些关于RMI的事情,而我不知道,我很想听听。无法解释的否决票只是破坏网站。
    while (true)
    {
        Thread.sleep(Integer.MAX_VALUE);
    }