I have been experimenting with Process
and ProcessBuilder
and come with this SSCCE.
import java.io.IOException;
public class TestProcess {
public static void main(String[] args) {
Process process = null;
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
try {
process = pb.start();
} catch (IOException e) {e.printStackTrace();}
//have some time to close notepad
try {
Thread.sleep(10*1000);
} catch (InterruptedException ignored) {}
try {
System.out.println(process.exitValue());
} catch (IllegalThreadStateException e) {
System.out.println(e);
}
if (process != null)
process.destroy();
/*try {
Thread.sleep(0, 1);
} catch (InterruptedException ignored) {}*/
System.out.println(process.exitValue());
}
}
destroy()
call does not show any problem on attempt to stop already terminated process. Why?It seems that destroy is asynchronous call (just sending a signal?) which results in exception in second exitValue()
java.lang.IllegalThreadStateException: process has not exited
Exception in thread "main" java.lang.IllegalThreadStateException: process has not exited
at java.lang.ProcessImpl.exitValue(ProcessImpl.java:246)
at TestProcess.main(TestProcess.java:30)
exitValue
never throws Exception, even though sleep value is just 1ms. Is it because of sleep()
overhead itself?
Second exitValue
would return 1. PS. I run it from Windows 7 and Eclipse.
I'm expecting that the destroy() method is calling the native windows function TerminateProcess. Looking at MSDN, I found this:
TerminateProcess is asynchronous; it initiates termination and returns immediately. If you need to be sure the process has terminated, call the WaitForSingleObject function with a handle to the process.
So I think it explain that destroy is indeed asynchronous.
Another extract from the same source:
The TerminateProcess function is used to unconditionally cause a process to exit.
I guess that "unconditionnally" can explain why the call of destroy() on a terminate process don't fail.
Hope this help. (really interesting question !)