ByteArrayOutputStream errStream = new MaxByteArrayOutputStream(nbytes);
executor.setStreamHandler(new PumpStreamHandler(outStream, errStream));
// Only run for N milliseconds
int timeout = appConf.getInt(AppConfig.EXEC_TIMEOUT_NAME, 0);
ExecuteWatchdog watchdog = new ExecuteWatchdog(timeout);
executor.setWatchdog(watchdog);
CommandLine cmd = makeCommandLine(program, args);
LOG.info("Running: " + cmd);
ExecBean res = new ExecBean();
if(Shell.WINDOWS){
//The default executor is sometimes causing failure on windows. hcat
// command sometimes returns non zero exit status with it. It seems
// to hit some race conditions on windows.
env = execEnv(env);
String[] envVals = new String[env.size()];
int i=0;
for( Entry<String, String> kv : env.entrySet()){
envVals[i++] = kv.getKey() + "=" + kv.getValue();
LOG.info("Setting " + kv.getKey() + "=" + kv.getValue());
}
Process proc;
synchronized (WindowsProcessLaunchLock) {
// To workaround the race condition issue with child processes
// inheriting unintended handles during process launch that can
// lead to hangs on reading output and error streams, we
// serialize process creation. More info available at:
// http://support.microsoft.com/kb/315939
proc = Runtime.getRuntime().exec(cmd.toStrings(), envVals);
}
//consume stderr
StreamOutputWriter errorGobbler = new
StreamOutputWriter(proc.getErrorStream(), "ERROR", errStream);
//consume stdout
StreamOutputWriter outputGobbler = new
StreamOutputWriter(proc.getInputStream(), "OUTPUT", outStream);
//start collecting input streams
errorGobbler.start();
outputGobbler.start();
//execute
try{
res.exitcode = proc.waitFor();
} catch (InterruptedException e) {
throw new IOException(e);
}
//flush
errorGobbler.out.flush();
outputGobbler.out.flush();
}
else {
res.exitcode = executor.execute(cmd, execEnv(env));
}
String enc = appConf.get(AppConfig.EXEC_ENCODING_NAME);
res.stdout = outStream.toString(enc);
res.stderr = errStream.toString(enc);
try {
watchdog.checkException();
}
catch (Exception ex) {
LOG.error("Command: " + cmd + " failed. res=" + res, ex);
}
if(watchdog.killedProcess()) {
String msg = " was terminated due to timeout(" + timeout + "ms). See " + AppConfig
.EXEC_TIMEOUT_NAME + " property";
LOG.warn("Command: " + cmd + msg + " res=" + res);
res.stderr += " Command " + msg;
}