예제 #1
0
  /**
   * Build the environment used for all exec calls.
   *
   * @return The environment variables.
   */
  public Map<String, String> execEnv(Map<String, String> env) {
    HashMap<String, String> res = new HashMap<String, String>();

    for (String key : appConf.getStrings(AppConfig.EXEC_ENVS_NAME)) {
      String val = System.getenv(key);
      if (val != null) {
        res.put(key, val);
      }
    }
    if (env != null) res.putAll(env);
    for (Map.Entry<String, String> envs : res.entrySet()) {
      LOG.info("Env " + envs.getKey() + "=" + envs.getValue());
    }
    return res;
  }
예제 #2
0
 private ExecServiceImpl() {
   avail = new Semaphore(appConf.getInt(AppConfig.EXEC_MAX_PROCS_NAME, 16));
 }
예제 #3
0
  private ExecBean auxRun(String program, List<String> args, Map<String, String> env)
      throws NotAuthorizedException, ExecuteException, IOException {
    DefaultExecutor executor = new DefaultExecutor();
    executor.setExitValues(null);

    // Setup stdout and stderr
    int nbytes = appConf.getInt(AppConfig.EXEC_MAX_BYTES_NAME, -1);
    ByteArrayOutputStream outStream = new MaxByteArrayOutputStream(nbytes);
    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;
    }
    if (res.exitcode != 0) {
      LOG.info("Command: " + cmd + " failed. res=" + res);
    }
    return res;
  }