package org.meaningfulweb.util; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.PumpStreamHandler; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ProcessUtils { private final static Logger LOG = LoggerFactory.getLogger(ProcessUtils.class); public static void runSystemCommand(SystemCommand systemCommand) { CommandLine commandLine = CommandLine.parse(systemCommand.getCommand(), systemCommand.getParams()); String commandRun = commandLine.toString(); systemCommand.setCommandRun(commandRun); DefaultExecutor executor = new DefaultExecutor(); int timeoutInSeconds = systemCommand.getTimeoutInSeconds(); ExecuteWatchdog watchdog = new ExecuteWatchdog((timeoutInSeconds > 0) ? timeoutInSeconds * 1000 : -1); executor.setWatchdog(watchdog); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PumpStreamHandler streamHandler = new PumpStreamHandler(baos); executor.setStreamHandler(streamHandler); File workingDirectory = systemCommand.getWorkingDirectory(); executor.setWorkingDirectory(workingDirectory != null ? workingDirectory : TempDirUtils.getTempDirectory()); systemCommand.setCommandRun(commandRun); int exitValue = -1; try { LOG.debug("Running command: " + commandRun); exitValue = executor.execute(commandLine); } catch (Exception e) { LOG.error("Command failed: " + commandRun, e); systemCommand.setException(e); } finally { systemCommand.setExitValue(exitValue); boolean failed = executor.isFailure(exitValue); systemCommand.setFailed(failed); boolean killed = failed && watchdog.killedProcess(); systemCommand.setKilled(killed); systemCommand.setOutput(baos.toString()); } IOUtils.closeQuietly(baos); } public static ProcessResponse runProcess(List<String> command, Map<String, String> envVars, File workingDir) throws IOException { // create the process including environment variables and working directory ProcessBuilder processBuilder = new ProcessBuilder(command); if (envVars != null && !envVars.isEmpty()) { Map<String, String> env = processBuilder.environment(); env.putAll(envVars); } processBuilder.directory(workingDir); Process process = processBuilder.start(); ProcessResponse response = new ProcessResponse(); // get the error stream content InputStream input = process.getErrorStream(); String errorResponse = IOUtils.toString(input); response.setError(errorResponse); // get the output stream content InputStream output = process.getInputStream(); String outputResponse = IOUtils.toString(output); response.setOutput(outputResponse); // wait for the process to exit int result = -1; try { result = process.waitFor(); } catch (InterruptedException ie) { // don't do anything on interrupted process } finally { // set the result and close all streams response.setResult(result); if (process != null) { IOUtils.closeQuietly(process.getOutputStream()); IOUtils.closeQuietly(process.getInputStream()); IOUtils.closeQuietly(process.getErrorStream()); process.destroy(); } } return response; } }