2015-10-06 265 views
-2

我有JAVA RMI的问题。Java RMI导致“NoSuchObjectException”

我有一个java ee应用程序正在运行,它使用rmi来调用特定的方法,这些方法必须针对每个客户实现。 供应商给了我一个示例RMI接口实现,以显示如何获取特定的主机接口运行。 原始代码片段看起来像张贴example1。 接口正在运行,但每隔2到3天停止工作,没有任何已知原因。接口的日志看起来像仍然在运行。 调用接口的glassfish服务器显示如下日志条目:

[#| 2015-10-01T16:27:53.446 + 0200 | SEVERE | glassfish3.1.2 | javax.enterprise.system.std.com .sun.enterprise.server.logging | _ThreadID = 106; _ThreadName =螺纹-2; | egatingMethodAccessorImpl.invoke(未知来源) 在java.lang.reflect.Method.invoke(未知来源) ...

应用程序错误日志显示如下条目:

2015-10-05 08:44:07,819 [http-thread-pool-8080(4)]错误medexter.arden.server.engine.DelegatingHostInterface - 方法evaluateRead on远程inter脸部无法正常工作。 java.rmi.NoSuchObjectException:在sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(来源不明) 没有这样的对象表 ...

我发现了几个线程像这样的: java.rmi.NoSuchObjectException: no such object in table

这告诉我垃圾收集可能是负责任的,并且注册表必须保持静态以防止GC破坏对象。 同时我尝试了不同的方式。我的最后一个(以某种方式显示我的绝望 - 每24小时重新启动界面应该不是最佳解决方案)发布在example2中。 目前我生成一个可执行的jar文件并将其作为应用程序启动。我想在稍后将它作为服务运行,但首先它应该没有任何错误地工作。

有没有人有一个想法,所描述的行为的原因可能是什么? 任何imporovement给定的代码apprechiated。我只是想让这些东西工作,而不是每隔几天就断开连接。

非常感谢你, 马丁

例1:

import java.rmi.AlreadyBoundException; 
import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.rmi.server.UnicastRemoteObject; 


public class SampleRMIProvider { 

    private static RmiRegistryThread thr; 

    public static void main(String[] args) { 
    SampleRMIProvider prv = new SampleRMIProvider(); 
    prv.init(); 
    } 

    public void init(){ 
    SampleRMIProvider.thr = new RmiRegistryThread(); 
    thr.start(); 
    } 

    public class RmiRegistryThread extends Thread { 

    public boolean run = true; 

    @Override 
    public void run() { 
     System.err.println("thread start"); 
     String name = "RMIHostInterface"; 
     int servicePorti = Integer.parseInt("18989"); 
     try { 
     RmiHostInterface engine = new RmiHostInterfaceImpl(); 
     RmiHostInterface stub = (RmiHostInterface) UnicastRemoteObject.exportObject(engine, 0); 
     Registry registry; 
     try { 
      registry = LocateRegistry.createRegistry(servicePorti); 
     } catch (RemoteException e) { 
      registry = LocateRegistry.getRegistry(servicePorti); 
     } 
     registry.bind(name, stub); 
     } catch (RemoteException e) { 
     e.printStackTrace(); 
     } catch (AlreadyBoundException e) { 
     e.printStackTrace(); 
     } 
     try { 
     while (this.run) { 
      Thread.sleep(10000); 
     }  
     } catch (InterruptedException e) { 
     e.printStackTrace(); 
     } 
    } 
    } 
} 

例2:

import java.rmi.AlreadyBoundException; 
import java.rmi.RemoteException; 
import java.rmi.registry.LocateRegistry; 
import java.rmi.registry.Registry; 
import java.rmi.server.UnicastRemoteObject; 


public class SampleRMIProvider extends Thread{ 

    private static Registry r = null; 

    @Override 
    public void run() { 
     String name = "RMIHostInterface"; 
     int servicePorti = Integer.parseInt("20002"); //18989 

     try { 
      RmiHostInterface engine = new SampleInterfaceImpl(); 
      RmiHostInterface stub = (RmiHostInterface) UnicastRemoteObject.exportObject(engine, 0); 

      try { 
       SampleRMIProvider.r = LocateRegistry.createRegistry(servicePorti); 
      } catch (RemoteException e) { 
       SampleRMIProvider.r = LocateRegistry.getRegistry(servicePorti); 
      } 
      SampleRMIProvider.r.bind(name, stub); 
     } catch (RemoteException e) { 
      e.printStackTrace(); 
     } catch (AlreadyBoundException e) { 
      e.printStackTrace(); 
     } 
     System.err.println("RMI Interface created..."); 
     try{ 
      while(true){ 
       Thread.sleep(10000); 
      } 
     } 
     catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 

     try { 
      while (true) { 
       //RMI Interface instanzieren 
       SampleRMIProvider provider = new SampleRMIProvider(); 
       provider.start(); 
       //Ein Tag pause 
       Thread.sleep(86400000); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

2015年10月14日 最后 - 这个小例子表明,对于工作的解决方案我。感谢您的有用建议。

​​3210
+1

'INT servicePorti =的Integer.parseInt( “20002”);'是只写'INT servicePorti = 20002的荒谬的方式;'。 – EJP

+0

任何时候当你发现一个有用的答案时,你应该考虑对其进行升级或接受,或者两者兼而有之。 – EJP

回答

0
  • 我不知道你说“没有已知的原因”,是什么意思时引起的异常的Javadoc文档。

  • 你说你已经读过注册表引用必须是静态的,但是你没有任何静态注册表引用。

尝试实施。

+0

感谢您的明确单词。我试着表达了,我想从GC的角度来看,在被引用对象(例子2)中初始化的静态引用应该和由main方法设置的静态引用具有相同的效果。这就是为什么我认为我实际上会有一个静态的参考,据称,应该没有什么是GC。我似乎并没有深刻理解GC的原则。我通过main()方法重新输入了代码并初始化了适当对象的静态注册表和接口引用。希望这种方法能做到。 – MST

+1

目前尚不清楚你的新代码是否有效,或者你是否正在问一个新问题,或者是同一个问题的另一个版本。注意你不需要保持线程运行,或者'main()'方法。如果你仍然有问题,你可以尝试对'SampleProvider'的静态引用... – EJP