How to add a timeout value when using Java's Runtime.exec()?
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 !}