我得到以下异常,我无法弄清楚为什么会发生这种情况。
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is: java.net.SocketException: Connection reset
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at Daemon$ShutDownProcedure.run(Daemon.java:126)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 5 more
我有一个守护进程类,负责在单独的 JVM 中启动服务器。在那个守护进程中,我有一个 ShutDownHook,它调用远程服务器对象上的一个方法,该方法在服务器上启动一个关闭过程。
守护进程本身也是一个导出的 RMI 对象,但在不同的端口上,这样我就可以远程启动服务器。这意味着守护进程已经在 1099 端口上创建了一个注册表监听,而服务器在 1098 端口上有一个注册表监听。
现在我还有一个可以关闭服务器并重新启动它的“ClientGui”。它既可以访问守护进程来启动服务器,也可以访问服务器来关闭它。
守护进程类:
//.....
private Daemon(String[] args){
try {
this.reg = LocateRegistry.createRegistry(1099);
this.stub = (DaemonRemote) UnicastRemoteObject.exportObject(this, 1099);
this.reg.rebind(DaemonRemote.class.getName(), this.stub);
this.arguments = args;
Runtime.getRuntime().addShutdownHook(new ShutDownProcedure());
} catch (RemoteException e) {
e.printStackTrace();
}
}
//....
public static void main(String[] args){
String initialargs = Arrays.stream(args).collect(Collectors.joining(" "));
String[] command = new String[] {"java", "-Xmx4g","-cp", System.getProperty("java.class.path", "."), Server.class.getName(),initialargs};
try {
p = new ProcessBuilder(command).inheritIO().redirectErrorStream(true).start();
} catch (Exception e) {
e.printStackTrace();
}
if(daemon == null)
daemon = new Daemon(args);
}
//....
private class ShutDownProcedure extends Thread {
@Override
public void run(){
if(p.isAlive()){
try {
Registry serverreg = LocateRegistry.getRegistry(null, 1098);
ServerRemote serverrmi = (ServerRemote) serverreg.lookup(ServerRemote.class.getName()); //this is the line where the exception occurs...
serverrmi.killServer();
} catch (IOException | NotBoundException | InterruptedException e) {
e.printStackTrace();
}
}
}
}
从我的 ClientGui 我访问远程服务器对象的方式与从守护程序完全相同,并且还可以毫无问题地调用 killServer() 方法。但是,当我按 CTRL+C 从守护程序启动 ShutDownHook 时,在尝试查找导出的服务器对象时会引发上述异常。
网络搜索没有给我任何关于如何解决这个问题的想法......但也许我正在寻找错误的方向......
非常感谢任何帮助,我提前感谢任何人!:)