是否可以从另一个虚拟机中杀死一个 Java 虚拟机?
我有一个 Java 应用程序,它启动另一个 Java 应用程序。 启动器有一个看门狗计时器,并从第二个虚拟机接收定期通知。 但是,如果没有收到通知,则应终止第二个虚拟机,并且启动程序将执行一些额外的清理活动。
问题是,有没有办法只使用java来做到这一点? 到目前为止,我必须使用一些本机方法来执行此操作,这在某种程度上很难看。
谢谢!
I have a Java application that launches another java application. The launcher has a watchdog timer and receives periodic notifications from the second VM. However, if no notifications are received then the second virtual machine should be killed and the launcher will perform some additional clean-up activities.
The question is, is there any way to do this using only java? so far I have to use some native methods to perform this operation and it is somehow ugly.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
您应该能够执行 java.lang.Runtime.exec 和 shell 命令。
You should be able to do that
java.lang.Runtime.exec
and shell commands.不完全是进程管理,但您可以在要启动的 java 虚拟机中启动 rmi 服务器,并绑定 remote 实例,其方法执行所需的任何清理操作并调用 System.exit()。 然后,第一个虚拟机可以调用该远程方法来关闭第二个虚拟机。
Not exactly process management, but you could start an rmi server in the java virtual machine you are launching, and bind a remote instance with a method that does whatever cleanup required and calls System.exit(). The first vm could then call that remote method to shutdown the second vm.
您可以让 java 代码在运行时检测平台并触发平台的终止进程命令。 这实际上是对您当前解决方案的改进。
还有 Process.destroy( ),如果您使用 进程构建器 API
You can have the java code detect the platform at runtime and fire off the platform's kill process command. This is really an refinement on your current solution.
There's also Process.destroy(), if you're using the ProcessBuilder API
java.lang.Process
有一个waitFor()
方法来等待进程终止,还有一个destroy()
方法来终止子进程。java.lang.Process
has awaitFor()
method to wait for a process to die, and adestroy()
method to kill the subprocess.好的,要点如下:
我使用 Process API 关闭第二个虚拟机,但它不起作用。
原因是我的第二个应用程序是 Eclipse RCP 应用程序,我使用附带的 eclipse.exe 启动器启动它。
但是,这意味着 Process API destroy() 方法将针对 eclipse.exe 进程。 终止该进程不会使 Java 进程受到损害。 因此,我的一位同事编写了一个小应用程序,它将杀死正确的应用程序。
因此,使用 Process API(并删除多余的中间步骤)的解决方案之一是摆脱 Eclipse 启动器,让我的第一个虚拟机复制其所有功能。
我想我得去上班了。
OK the twist of the gist is as follows:
I was using the Process API to close the second virtual machine, but it wouldn't work.
The reason is that my second application is an Eclipse RCP Application, and I launched it using the eclipse.exe launcher included.
However, that means that the Process API destroy() method will target the eclipse.exe process. Killing this process leaves the Java Process unscathed. So, one of my colleagues here wrote a small application that will kill the right application.
So one of the solutions to use the Process API (and remove redundant middle steps) is to get away with the Eclipse launcher, having my first virtual machine duplicate all its functionality.
I guess I will have to get to work.
通常的方法是调用 Process.destroy()...但是,这是一个不完整的解决方案,因为在 *nix 上使用 sun JVM 时,销毁映射到 SIGTERM,而不能保证终止该过程(为此您还需要 SIGKILL)。 最终结果是您无法使用 Java 进行真正的流程管理。
关于此问题有一些未解决的错误,请参阅:
链接文本
The usual way to do this is to call
Process.destroy()
... however it is an incomplete solution since when using the sun JVM on *nix destroy maps onto a SIGTERM which is not guaranteed to terminate the process (for that you need SIGKILL as well). The net result is that you can't do real process management using Java.There are some open bugs about this issue see:
link text
您还可以在第二个 JVM 上发布一个服务(通过 burlap、hessian 等),该服务调用 System.exit() 并从看门狗 JVM 中使用它。 如果您只想在第二个 JVM 停止发送这些定期通知时将其关闭,它可能不会处于响应服务调用的状态。
使用 java.lang.Runtime.exec() 调用 shell 命令可能是您最好的选择。
You could also publish a service (via burlap, hessian, etc) on the second JVM that calls System.exit() and consume it from the watchdog JVM. If you only want to shut the second JVM down when it stops sending those periodic notifications, it might not be in a state to respond to the service call.
Calling shell commands with java.lang.Runtime.exec() is probably your best bet.
您可以使用 java.lang.Process做你想做的事。 创建嵌套流程并拥有对 Process 实例的引用后,您就可以获得对其标准输出流和错误流的引用。 您可以定期监视这些进程,如果您想关闭进程,则可以调用 .destroy() 。 整个事情可能看起来像这样:
希望这有帮助,
肖恩
You can use java.lang.Process to do what you want. Once you have created the nested process and have a reference to the Process instance, you can get references to its standard out and err streams. You can periodically monitor those, and call .destroy() if you want to close the process. The whole thing might look something like this:
Hope this helps,
Sean
我可能错过了一些东西,但你不能调用
Process
由Runtime.exec()
?I may be missing something but can't you call the
destroy()
method on theProcess
object returned byRuntime.exec()
?