In the code snippet provided below a new process is started from Java. The new process is a shell that starts some Linux utilities. The problem I have is that 'atop' and 'awk' utilities are still running after calling process.destroy()
. I have tried process.destroyForcibly()
but no improvements. The variable continueMonitoring
is updated from a different thread.
Question destroy all proceses does not address the problem of stooping processes that use pipe mechanism between them, in my case I don't even have the PIDs for all the processes that are started.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
public class MinimalClient {
boolean continueMonitoring = true;
public static void main(String[] args) throws InterruptedException {
MinimalClient mc = new MinimalClient();
mc.startMonitoring();
}
public void startMonitoring() throws InterruptedException {
Thread cpuMonit = new Thread(new Runnable() {
@Override
public void run() {
String line;
Process process;
StringBuilder commandOutput = new StringBuilder();
String processPid = getPid();
String[] cmd = {
"/bin/sh",
"-c",
" atop 1 -a | unbuffer -p awk '/" + processPid + "|nmap/ {print $1 \" \" $11}'"
};
try {
process = Runtime.getRuntime().exec(cmd);
Field pid = process.getClass().getDeclaredField("pid");
pid.setAccessible(true);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ( continueMonitoring && (line = br.readLine()) != null) {
commandOutput.append(line + "\n");
}
process.destroy();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
});
cpuMonit.start();
Thread.sleep(10000);
continueMonitoring = false;
}
private String getPid() {
String processName = java.lang.management.ManagementFactory.getRuntimeMXBean().getName();
return processName.split("@")[0];
}
}