我有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
'INT servicePorti =的Integer.parseInt( “20002”);'是只写'INT servicePorti = 20002的荒谬的方式;'。 – EJP
任何时候当你发现一个有用的答案时,你应该考虑对其进行升级或接受,或者两者兼而有之。 – EJP