package zh.solr.se.indexer.util.process; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import zh.solr.se.indexer.util.IoUtil; import zh.solr.se.indexer.util.StringUtil; public class ProcessRunner { private static final Log logger = LogFactory.getLog(ProcessRunner.class); public int execFromClassPath(String[] command) throws IOException { assert (command != null && command.length > 0); // the first element of the command array must be the file name of the executable String fileName = command[0]; // copy the executable from class path to file system, assuming it is at the root of class path String classPathDir = "/"; String fullPath = copyFileFromClassPathToWorkingDirectory(fileName, classPathDir); logger.info("Full path to script: " + fullPath); command[0] = fullPath; // run the executable int exitValue = execComamnd(command, null, null); // remove the executable from the file system (new File(fullPath)).delete(); return exitValue; } public int execComamnd(String[] command, String[] env, String commandDir) { File dir = (commandDir == null) ? null : new File(commandDir); int exitValue = -1; try { // execute the command Runtime rt = Runtime.getRuntime(); logger.info("Running " + constructCommandString(command, env, commandDir)); Process proc = rt.exec(command, env, dir); // check for error message and output StreamConsumer errorConsumer= new StreamConsumer(proc.getErrorStream(), "ERROR"); StreamConsumer outputConsumer = new StreamConsumer(proc.getInputStream(), "OUTPUT"); errorConsumer.start(); outputConsumer.start(); // wait until the process finishes exitValue = proc.waitFor(); } catch (Throwable t) { t.printStackTrace(); exitValue = 4; } return exitValue; } private String copyFileFromClassPathToWorkingDirectory(String fileName, String classPathDir) throws IOException { assert fileName != null; String workingDir = System.getProperty("user.dir"); String inPath = IoUtil.concatenatePaths(classPathDir, fileName); String outPath = IoUtil.concatenatePaths(workingDir, fileName); logger.info("Working dir: " + workingDir); logger.info("Path to script: " + outPath); File outFile = new File(outPath); outFile.createNewFile(); outFile.setExecutable(true); // copy the file from class path to working directory InputStream inStream = ProcessRunner.class.getResourceAsStream(inPath); FileOutputStream outStream = new FileOutputStream(outFile); int bytesRead; byte[] buf = new byte[1024]; while((bytesRead=inStream.read(buf))!=-1){ String str = new String(buf); str = str.replaceAll ( "\r", "" ); buf = str.getBytes(); outStream.write(buf,0,buf.length); buf = new byte[1024]; } outStream.flush(); outStream.close(); inStream.close(); return outPath; } private String constructCommandString(String[] command, String[] env, String commandDir) { StringBuilder builder = new StringBuilder(IoUtil.concatenatePaths(commandDir, command[0])); for (int i = 1; i < command.length; i++) { builder.append(" "); builder.append(command[i]); } if (env != null && env.length > 0) { builder.append(StringUtil.NEW_LINE); builder.append("env:"); for (String envStr : env) { builder.append(", ").append(envStr); } } return builder.toString(); } }