我有一个 Java 应用程序,它启动另一个 Java 应用程序。启动器有一个看门狗计时器,并从第二个虚拟机接收定期通知。但是,如果没有收到通知,则应终止第二个虚拟机,并且启动器将执行一些额外的清理活动。

问题是,有没有办法只使用java来做到这一点?到目前为止,我必须使用一些本机方法来执行此操作,这在某种程度上很难看。

谢谢!

有帮助吗?

解决方案

我可能错过了一些东西,但你不能打电话给 destroy() 方法上的 Process 返回的对象 Runtime.exec()?

其他提示

您可以使用 java.lang.Process 做你想做的事。创建嵌套流程并拥有对 Process 实例的引用后,您就可以获得对其标准输出流和错误流的引用。您可以定期监视这些进程,如果您想关闭进程,则可以调用 .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
}

希望这可以帮助,

肖恩

您还可以在第二个 JVM 上发布一个服务(通过 burlap、hessian 等),该服务调用 System.exit() 并从看门狗 JVM 中使用它。如果您只想在第二个 JVM 停止发送这些定期通知时将其关闭,它可能不会处于响应服务调用的状态。

使用 java.lang.Runtime.exec() 调用 shell 命令可能是您最好的选择。

通常的方法是调用 Process.destroy()...然而,这是一个不完整的解决方案,因为在 *nix 上使用 sun JVM 时,销毁映射到 SIGTERM,这不能保证终止进程(为此您还需要 SIGKILL)。最终结果是您无法使用 Java 进行真正的流程管理。

关于此问题有一些未解决的错误,请参阅:链接文本

java.lang.Process 有一个 waitFor() 方法来等待进程死亡,还有一个 destroy() 方法来杀死子进程。

好的,要点如下:

我使用 Process API 关闭第二个虚拟机,但它不起作用。

原因是我的第二个应用程序是 Eclipse RCP 应用程序,我使用附带的 eclipse.exe 启动器启动它。

但是,这意味着 Process API destroy() 方法将针对 eclipse.exe 进程。终止该进程不会使 Java 进程受到损害。因此,我的一位同事编写了一个小应用程序,它将杀死正确的应用程序。

因此,使用 Process API(并删除多余的中间步骤)的解决方案之一是摆脱 Eclipse 启动器,让我的第一个虚拟机复制其所有功能。

我想我得去上班了。

您应该能够执行 java.lang.Runtime.exec 和 shell 命令。

您可以让 java 代码在运行时检测平台并触发平台的终止进程命令。这实际上是对您当前解决方案的改进。

还有 进程.destroy(), ,如果您正在使用 流程构建器 应用程序编程接口

不完全是进程管理,但你可以在你正在启动的java虚拟机中启动一个rmi服务器,并绑定一个 偏僻的 具有执行所需清理操作并调用 System.exit() 的方法的实例。然后,第一个虚拟机可以调用该远程方法来关闭第二个虚拟机。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top