How to add a timeout value when using Java's Runtime.exec()? How to add a timeout value when using Java's Runtime.exec()? java java

How to add a timeout value when using Java's Runtime.exec()?


If you're using Java 8 or later you could simply use the new waitFor with timeout:

Process p = ...if(!p.waitFor(1, TimeUnit.MINUTES)) {    //timeout - kill the process.     p.destroy(); // consider using destroyForcibly instead}


public static int executeCommandLine(final String commandLine,                                     final boolean printOutput,                                     final boolean printError,                                     final long timeout)      throws IOException, InterruptedException, TimeoutException {  Runtime runtime = Runtime.getRuntime();  Process process = runtime.exec(commandLine);  /* Set up process I/O. */  ...   Worker worker = new Worker(process);  worker.start();  try {    worker.join(timeout);    if (worker.exit != null)      return worker.exit;    else      throw new TimeoutException();  } catch(InterruptedException ex) {    worker.interrupt();    Thread.currentThread().interrupt();    throw ex;  } finally {    process.destroyForcibly();  }}private static class Worker extends Thread {  private final Process process;  private Integer exit;  private Worker(Process process) {    this.process = process;  }  public void run() {    try {       exit = process.waitFor();    } catch (InterruptedException ignore) {      return;    }  }  }


Following the answer by erickson, I created a more generic way to do the same thing.

public class ProcessWithTimeout extends Thread{    private Process m_process;    private int m_exitCode = Integer.MIN_VALUE;    public ProcessWithTimeout(Process p_process)    {        m_process = p_process;    }    public int waitForProcess(int p_timeoutMilliseconds)    {        this.start();        try        {            this.join(p_timeoutMilliseconds);        }        catch (InterruptedException e)        {            this.interrupt();        }        return m_exitCode;    }    @Override    public void run()    {        try        {             m_exitCode = m_process.waitFor();        }        catch (InterruptedException ignore)        {            // Do nothing        }        catch (Exception ex)        {            // Unexpected exception        }    }}

Now, all you have to do is as follows:

Process process = Runtime.getRuntime().exec("<your command goes here>");ProcessWithTimeout processWithTimeout = new ProcessWithTimeout(process);int exitCode = processWithTimeout.waitForProcess(5000);if (exitCode == Integer.MIN_VALUE){    // Timeout}else{    // No timeout !}