Reputation: 1111
I have the following code:
Process proc;
try
{
ProcessBuilder procBuilder = new ProcessBuilder(/* some args */);
proc = procBuilder.start();
if (proc.waitFor(30000, TimeUnit.MILLISECONDS))
{
//Etc...
}
else
{
//Handle it
}
}
catch (InterruptedException ie)
{
currentThread().interrupt();
}
finally
{
//What goes here?
}
I have tried to find some source that indicates whether it is required to call proc.destroy()
(should I check isAlive()
before calling destroy?), and to manually close its input/output/error streams, to no avail. Not even the official documentation makes this clear, from what I can tell.
Is it necessary, or even just good practice, to perform these operations when I am finished with the spawned process?
Upvotes: 5
Views: 1384
Reputation: 9121
While Michael's answer correctly addresses the "destroy" part of the answer and I echo the advice to use a finally
block as suggested, the original question also asked about closing streams and there's a subtle difference.
On Linux, macOS, and BSD Unix platforms, the destroy()
implementations close the streams automatically, so for these platforms it is sufficient to just destroy the process and get the stream closures as well.
However, on the Windows and Solaris (SunOS) platforms, the native destroy()
implementation simply executes TerminateProcess
or kill
and does not close the streams. There is even a StreamsSurviveDestroy
test case (Solaris-only) in the JDK8 source code.
So if you are supporting Windows or Solaris in your code, you should attempt to close the input, output, and error streams in addition to adding a destroy()
or destroyForcibly()
call in a finally
block. This stream closure can be done either before or after the destroy call.
Upvotes: 3
Reputation: 44150
It's a good idea to call process.destroyForcibly()
in the finally block. waitFor
will not kill the process if it does not finish before the timeout, so in a situation where the spawned process hangs indefinitely, if you do not kill it then it could stick around forever.
Another use-case is suppose your process takes around 25 seconds to terminate normally. Suppose your thread is interrupted almost immediately after starting. It's probably better to kill the process rather than leave it running all that time, since the result will never be used anyway.
As for the streams, see Properly closing Java Process InputStream from getInputStream
Upvotes: 4