I have a cross-platform (Linux and Windows) program, currently running on Java 7. The program will launch one or more workers as Processes using ProcessBuilder (using instructions from here):
String javaHome = System.getProperty("java.home");
String javaBin = javaHome + File.separator + "bin" + File.separator + "java";
String classpath = System.getProperty("java.class.path");
String className = MyClass.class.getCanonicalName();
ProcessBuilder pb = new ProcessBuilder(javaBin, "-cp", classpath, className);
pb.directory(null);
pb.inheritIO();
Process p = pb.start();
The reason for this approach was designed to solve an issue with the older system, which ran the workers in threads. However, due to the nature of the code we're running, it's possible for the workers to enter a loop from which they won't exit. Since Java does not support the idea of terminating a thread, we moved to a completely separate process under the assumption that Java could actually kill a process.
However, it appears that isn't true in Java 7 - Process.destroy() sends a SIGTERM, not a SIGKILL, and our stalled workers aren't being killed as we'd expect. Java 8 implemented Process.destroyForcibly(), which would solve the problem, but upgrading the core Java version is likely to introduce a number of bugs, and upgrading is something we'd like to avoid if at all possible.
Most other solutions involve reflecting into the UNIXProcess class, getting the pid, and piping a kill command to the shell. However, this won't work for us as we run on Windows, where Process does not have any grasp of a pid, and further forces us to include OS-specific code paths which is extremely undesirable.
Is there some reliable way to get Java to terminate something?