是否可以从另一个虚拟机中杀死Java虚拟机?
我有一个Java应用程序,可以启动另一个Java应用程序。启动器具有看门狗计时器,并从第二个VM接收定期通知。但是,如果未收到通知,则第二台虚拟机应被杀死,启动器将执行一些其他清理活动。
问题是,有什么方法可以仅使用java来做到这一点?到目前为止,我必须使用一些本机方法来执行此操作,而且这种方法很难看。
谢谢!
解决方案
回答
我们应该能够执行java.lang.Runtime.exec和shell命令。
回答
我们可以让Java代码在运行时检测平台并启动平台的kill process命令。这实际上是对我们当前解决方案的改进。
如果我们使用的是ProcessBuilder API,则还有Process.destroy()
回答
我可能缺少了一些东西,但是我们不能在Runtime.exec()返回的Process对象上调用destroy()方法吗?
回答
我们还可以在第二个JVM上发布服务(通过粗麻布,粗麻布等),该服务调用System.exit()并从看门狗JVM使用它。如果我们只想在第二个JVM停止发送那些定期通知时将其关闭,则它可能未处于响应服务调用的状态。
用java.lang.Runtime.exec()调用shell命令可能是最好的选择。
回答
不完全是过程管理,但是我们可以在正在启动的Java虚拟机中启动rmi服务器,并使用执行所需清理操作并调用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()方法来杀死子进程。
回答
确定要点如下:
我正在使用Process API关闭第二个虚拟机,但是无法正常工作。
原因是我的第二个应用程序是Eclipse RCP应用程序,我使用附带的eclipse.exe启动器启动了它。
但是,这意味着Process API destroy()方法将以eclipse.exe进程为目标。终止此进程将毫发无损。因此,我的一位同事在这里编写了一个小型应用程序,它将杀死正确的应用程序。
因此,使用Process API(并删除多余的中间步骤)的解决方案之一就是放弃Eclipse启动器,让我的第一台虚拟机复制其所有功能。
我想我必须去上班。
回答
通常的方法是调用Process.destroy()...,但这是一个不完整的解决方案,因为在* nix上使用sun JVM时,将映射映射到SIGTERM上并不能保证终止进程(为此,我们需要SIGKILL)。最终结果是我们无法使用Java进行真正的流程管理。
关于此问题有一些未解决的错误,请参见:
连结文字