项目场景:
需要用Java调用命令行执行命令,jdk版本是1.8。
问题描述
调用命令行的接口写完了,发现还需要个关闭的接口,试了
process.destroy();
process.destroyForcibly();
因为调用了不同的接口,是不同的process 所以中止不掉。
使用
String name = ManagementFactory.getRuntimeMXBean().getName();
Long.parseLong(name.split("@")[0]);
发现获取到的是整个服务的进程号,停止就直接停止整个服务了,这种肯定是不行的。
原因分析:
想着可不可以把整个process 和命令存起来,然后调用的时候获取process然后去调用destroyForcibly()方法停止,找了半天,发现process存不起来,只能给里面的参数存起来,但是jdk8获取不到进程号,只能重新想办法。
解决方案:
最后偶然看到jdk8获取进程号的帖子,试了一下,可以获取到子进程的进程号,果断采用了,忘记了是哪个帖子了,打开的属实有点多。最后附上成功获取到子进程进程号的代码和杀进程的代码。
获取子进程的进程号
pid = process.getClass().getDeclaredField("pid");
pid.setAccessible(true);
String i = String.valueOf(pid.getInt(process))
杀掉进程的方法
public ResponseEntity<Integer> stopByPid(String pid) {
if (!StringUtils.hasText(pid)) {
throw new BadRequestException("Pid cannot be empty");
}
String command = "kill -9 " + pid;
log.info(command);
Process process = null;
Integer exitCode = 0;
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("bash", "-c", command);
try {
process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
log.error(line);
}
exitCode = process.waitFor();
log.info("Exited with error code : " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return ResponseEntity.ok(exitCode);
}