Java RMI导致“NoSuchObjectException”
我对JavaRMI有一个问题
我有一个JavaEE应用程序正在运行,它使用rmi调用特定的方法,这些方法必须针对每个客户具体实现。 供应商给了我一个RMI接口实现示例,以说明如何运行特定的hostinterface。 原始代码片段看起来像发布的示例1。 该接口正在运行,但每隔2到3天就会停止工作,原因不明。接口日志看起来仍在运行。 调用接口的glassfish服务器显示如下日志条目:
[#|2015-10-01T16:27:53.446+0200严重glassfish3.1.2 | javax.enterprise.system.std.com.sun.enterprise.server.logging | u ThreadID=106;| u ThreadName=Thread-2;| egatingMethodAccessorImpl.invoke(未知源) 在爪哇。朗。反思。方法调用(未知源) ...
应用程序错误日志显示如下条目:
2015-10-05 08:44:07819[http-thread-pool-8080(4)]错误medexter。阿登。服务器发动机DelegatingHostInterface-远程接口上的evaluateRead方法无法正常工作。 JAVA马绍尔群岛共和国。NoSuchObjectException:表中没有此类对象 在太阳下。马绍尔群岛共和国。运输StreamRemoteCall。从服务器接收的例外(未知源) ...
我发现了几个像这样的线程: java.rmi.NoSuchObjectException: no such object in table
这告诉我垃圾收集可能负责,注册表必须保持静态,以防止GC破坏对象。 与此同时,我尝试了不同的方法。我的最后一个例子(不知何故显示了我的失望——每24小时重新启动一次界面不应该是黄金解决方案)发布在示例2中。 目前,我生成了一个可执行的jar文件,并将其作为应用程序启动。我想让它以后作为一个服务运行,但首先它应该可以正常工作,没有任何错误
有没有人知道,所描述行为的原因是什么? 对给定代码的任何修改均应予以批准。我只是想让这些东西正常工作,而不是每隔几天就失去连接
多谢各位, 马丁
例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();
}
}
}
14.10.2015 最后,这个最小的例子展示了一个对我有效的解决方案。谢谢你的建议
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 Registry r = null;
private static SampleHostInterfaceImpl hif = null;
private static RmiHostInterface stub = null;
SampleRMIProvider(){
try{
SampleRMIProvider.r.bind("RMIHostInterface", SampleRMIProvider.stub);
}
catch(RemoteException | AlreadyBoundException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
//setup static references to prevent from beeing collected by GC
try {
SampleRMIProvider.hif = new SampleHostInterfaceImpl();
SampleRMIProvider.stub = (RmiHostInterface) UnicastRemoteObject.exportObject(SampleRMIProvider.hif, 0);
try {
SampleRMIProvider.r = LocateRegistry.createRegistry(20002);
} catch (RemoteException e) {
SampleRMIProvider.r = LocateRegistry.getRegistry(20002);
}
} catch (RemoteException e) {
e.printStackTrace();
}
new SampleRMIProvider();
}
}
# 1 楼答案
我不知道你所说的“未知原因”是什么意思,当原因记录在异常的Javadoc中时
您说您已经读到注册表引用必须是静态的,但是您没有任何静态注册表引用
尝试实现这一点