Java:终止由Runtime.getRuntime().exec()运行的进程

6
我需要编写一段代码,它能够:
  1. 使用 Runtime.getRuntime().exec("java -jar MyServerRunner -port MYPORT"); 运行 Unix 进程。
  2. 通过执行命令 lsof -t -i: MYPORT 来从 Java 代码中查找进程的 PID。
  3. 通过 pid kill -9 PID(也可以通过执行 Java 代码中的命令)来杀掉该进程。
  4. 然后执行其他命令。
但是,如果我使用 Runtime.getRuntime().exec() 命令来执行此命令,则我的程序将以退出代码 137 的形式退出。这意味着当我运行 Runtime.getRuntime().exec("kill -9 PID") 时,我会杀死 My java 程序的进程,而不是从代码运行的程序。
那么,如何仅杀死我从代码中运行的进程?
P.S. 或许我应该使用 ProcessBuilder?

2
如果您正在使用Runtime.getRuntime()来运行另一个Java进程,那么您正在做一些错误的事情。为什么不直接在Thread中运行类呢? - Boris the Spider
  1. 如果您使用“-9”终止进程,那么您也在做错事情。如果进程有一个端口,它应该还有一个可以发送到该端口的关闭命令。对于知道自己在做什么(并记录日志)的管理员来说,“kill -9”是最后的手段。它不应该内置在应用程序中。
  2. 启动的Java进程退出时出现“137”的事实与您终止了错误的进程无关。
- user207421
3个回答

12

你可以使用destroy方法在Java应用程序中终止你启动的子进程:

Process p = Runtime.getRuntime().exec("java -jar MyServerRunner -port MYPORT");
p.destroy();

同时请注意,将那段代码放在一个单独的线程中运行可能比放在一个单独的进程中更有意义。


Runtime.exec 在另一个线程中运行其他进程。还要注意,p.destroy() 发送的是 SIGTERM,而不是 SIGINT / SIGHUP / SIGKILL - Luke Hutchison
我的意思是,在同一个JVM中运行MyServerRunner可能比在不同的进程中运行更可取,但显然这取决于具体情况。 - assylias

1
您可以使用.exec("ps|grep <your process name>");,然后解析结果以获取PID,最后执行.exec("kill PID");
因此,您的进程被终止,但Android应用程序仍然在运行。

你能否请澄清如何获取PID?另外,有一个小修正ps | grep。 - vikramvi
这就是我一直在寻找的内容。根据你的回答,它给出了PID,但与命令行PID不匹配。我不确定为什么?String s = null; Process p = Runtime.getRuntime().exec("pgrep -f selenium-server-standalone");BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));while ((s = stdInput.readLine()) != null) { System.out.println(s); } - vikramvi
从Java 9开始,您只需调用proc.pid()即可获取pid。 - Luke Hutchison

1

您可以使用反射在Unix中获取pid(我知道这是一个坏主意:)并调用kill;

Process proc = Runtime.getRuntime().exec(
   new String[] {"java","-classpath",System.getProperty("java.class.path"),... });
Class<?> cProcessImpl = proc.getClass();
Field fPid = cProcessImpl.getDeclaredField("pid");
if (!fPid.isAccessible()) {
    fPid.setAccessible(true);
}
Runtime.getRuntime().exec("kill -9 " + fPid.getInt(proc));

从Java 9开始,你只需调用 proc.pid() 即可获得进程的PID。 - Luke Hutchison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接