@Override public RESULT awaitAtMost(CountDownWatch timeout) throws ExecutionException, TimeoutExecutionException { return awaitAtMost(timeout.timeout(), timeout.getTimeUnit()); }
@Override public boolean hasFailed() { if (!isFinished()) { throw new IllegalStateException("Process " + processName + " is not yet finished, cannot determine whether it failed."); } // check whether we have specified exit value and if not adhere to defaults if (allowedExitCodes.isEmpty()) { return processReference.getProcess().exitValue() != 0; } return !allowedExitCodes.contains(processReference.getProcess().exitValue()); }
@Override public boolean isFinished() { // if process is marked as finished, consider it so if (isMarkedAsFinished()) { return true; } try { if (!processReference.isInitialized()) { return false; } processReference.getProcess().exitValue(); return true; } catch (IllegalThreadStateException e) { return false; } }
@Override public Execution<Process> execute() throws ExecutionException { // here we rewrap future based execution into process based execution to get better details about execution Execution<Process> processFutureExecution = super.execute(); Process process = processFutureExecution.await(); ProcessReference ref = new ProcessReference(command.getProgramName()); ref.setProcess(process); ProcessBasedExecution<Process> execution = new ProcessBasedExecution<Process>(processFutureExecution, ref, command.getProgramName(), allowedExitCodes); // register shutdown hook if (!runsAsDaemon) { execution.registerShutdownHook(); } return execution; }
@Override public RESULT until(CountDownWatch timeout, ExecutionCondition<RESULT> condition) throws ExecutionException, TimeoutExecutionException { return until(timeout.timeout(), timeout.getTimeUnit(), condition); } }
@Override public Execution<RESULT> terminate() throws ExecutionException { // if process has not yet started, terminate Future that would lead to its creation if (!processReference.isInitialized()) { processFutureExecution.terminate(); return markAsFinished(); } processReference.getProcess().destroy(); try { processReference.getProcess().waitFor(); } catch (InterruptedException e) { log.log(Level.WARNING, "Ignoring Interuption Exception while terminating the process {0}", processName); } // close STDIN of the process, if any OutputStream ostream = processReference.getProcess().getOutputStream(); try { if (ostream != null) { ostream.flush(); ostream.close(); } } catch (IOException e) { log.log(Level.WARNING, "Ignoring IO exception while terminating the process {0}", processName); } return this; }
@Override public Execution<ProcessResult> execute() throws ExecutionException { // here we rewrap future based execution into process based execution to get better details about execution // and ability to terminate the process this.processRef = new ProcessReference(commandBuilder.build().getProgramName()); Execution<ProcessResult> processFutureExecution = super.execute(); ProcessBasedExecution<ProcessResult> execution = new ProcessBasedExecution<ProcessResult>(processFutureExecution, processRef, commandBuilder.build().getProgramName(), allowedExitCodes); return execution; }