我有一个启动另一个Java应用程序的Java应用程序。启动器有一个看门狗定时器并从第二个虚拟机接收定期通知。但是,如果没有收到通知,则应该杀死第二台虚拟机,启动程序将执行一些额外的清理活动。是否有可能从另一台虚拟机中杀死Java虚拟机?
问题是,有没有什么办法只用java来做到这一点?到目前为止,我必须使用一些本地方法来执行此操作,并且它有点难看。
谢谢!
我有一个启动另一个Java应用程序的Java应用程序。启动器有一个看门狗定时器并从第二个虚拟机接收定期通知。但是,如果没有收到通知,则应该杀死第二台虚拟机,启动程序将执行一些额外的清理活动。是否有可能从另一台虚拟机中杀死Java虚拟机?
问题是,有没有什么办法只用java来做到这一点?到目前为止,我必须使用一些本地方法来执行此操作,并且它有点难看。
谢谢!
我可能失去了一些东西,但你不能调用destroy()
方法,通过Runtime.exec()
返回的Process
对象?
你应该能够做到这一点java.lang.Runtime.exec和shell命令。
您可以让java代码在运行时检测平台并启动平台的kill process命令。这实际上是对当前解决方案的改进。
还有Process.destroy(),如果你使用的ProcessBuilder API
你也可以发布服务(通过粗麻布,麻袋等)上调用System.exit第二JVM()和看门狗JVM使用它。如果您只想在停止发送那些定期通知时关闭第二个JVM,则可能不处于响应服务调用的状态。
与java.lang.Runtime.exec调用shell命令()可能是你最好的选择。
不完全是进程管理,但是您可以在启动的java虚拟机中启动rmi服务器,并将remote实例绑定到一个方法,该方法执行所需的清理并调用System.exit()。然后第一个虚拟机可以调用这个远程方法关闭第二个虚拟机。
您可以使用java.lang.Process做你想要什么。一旦你创建了嵌套的进程并且拥有对Process实例的引用,你就可以获得对它的标准out和err流的引用。你可以定期监视这些,如果你想关闭这个过程,可以调用.destroy()。整个事情会是这个样子:
Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
/*
TODO: read from the std out or std err (or get notifications some other way)
Then put the real "kill-me" logic here instead of if (false)
*/
if (false) {
nestedProcess.destroy();
//perform post-destruction cleanup here
return;
}
Thread.currentThread().sleep(1000L); //wait for a bit
}
希望这有助于
肖恩
java.lang.Process中有一个WAITFOR()方法来等待一个进程死亡,并且destroy()方法杀死子进程。
OK主旨的扭曲如下:
我所用的过程API关闭第二个虚拟机,但它是行不通的。
的原因是我的第二个应用是一个Eclipse RCP应用程序,我启动它使用包括的eclipse.exe启动。
然而,这意味着该过程API destroy()方法将针对的eclipse.exe过程。杀死这个进程不会损害Java进程。所以,我的一位同事在这里写了一个小应用程序,它会杀死正确的应用程序。
因此,使用Process API(并删除冗余中间步骤)的解决方案之一就是摆脱Eclipse启动器,让我的第一个虚拟机复制其所有功能。我想我将不得不去工作。
执行此操作的常用方法是调用Process.destroy()...但它是一个不完整的解决方案,因为在* nix上使用sun JVM将映射映射到不保证终止进程的SIGTERM(为此你也需要SIGKILL)。最终的结果是,你不能使用Java来进行真正的流程管理。
有对这个问题的一些开放的错误,请参阅: link text