2010-07-27 5 views
3

У меня есть следующий фрагмент кода:Чтение потоков из Java Runtime.exec

Process proc = runtime.exec(command); 
errorGobbler = new ErrorStreamGobbler(proc.getErrorStream(), logErrors, mdcMap); 
outputGobbler = new OutputStreamGobbler(proc.getInputStream(), mdcMap); 
executor.execute(errorGobbler); 
executor.execute(outputGobbler); 
processExitCode = proc.waitFor(); 

где gobblers являются Runnable ы, которые используют BufferedReader для чтения входных и ошибок потоков процесса, выполняющего. Хотя это работает большую часть времени, я получаю случайное окно (около 2 минут или около того), где я получаю processExitCode как 0, что указывает на нормальное завершение, но в потоках ввода и ошибок ничего нет - ничего, из потока.

Как я уже указывал ранее, это работает большую часть времени, но этот провал происходит раз в то время - и я полностью озадачен. Есть идеи?

Тряпки

+0

Немного больше контекста - это многопоточное приложение, в котором происходит много Runtime.exec(). Rags – ragstorooks

+0

Вы имеете в виду, что поточные кабачки блокируются навсегда? – EJP

+0

Да, да! Они просто висят ... – ragstorooks

ответ

11

Я боролся с такой же вопросов. Я не могу вспомнить, что именно не так (может быть, я забыл сбросить/закрыть потоки правильно или что-то еще ...). В любом случае, вот что я придумал.

/** 
* Handle communication with a process, reading its output/error and feeding its input 
* @param process The process to execute 
* @param _in Reader that will feed the input pipe of the process 
* @param out Writer that will receive the output of the process 
* @param err Writer that will receive the error pipe of the process 
*/ 
public static void communicate(
     Process process, 
     final Reader _in, 
     final Writer out, 
     final Writer err) 
{ 
    // Buffer the input reader 
    final BufferedReader in = new BufferedReader(_in); 

    // Final versions of the the params, to be used within the threads 
    final BufferedReader stdOut = new BufferedReader(new InputStreamReader(process.getInputStream())); 
    final BufferedReader stdErr = new BufferedReader(new InputStreamReader(process.getErrorStream())); 
    final BufferedWriter stdIn = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); 

    // Thread that reads std out and feeds the writer given in input 
    new Thread() { 
     @Override public void run() { 
      String line; 
      try { 
       while ((line = stdOut.readLine()) != null) { 
        out.write(line + newline); 
       } 
      } catch (Exception e) {throw new Error(e);} 
      try { 
       out.flush(); 
       out.close(); 
      } catch (IOException e) { /* Who cares ?*/ } 
     } 
    }.start(); // Starts now 

    // Thread that reads std err and feeds the writer given in input 
    new Thread() { 
     @Override public void run() { 
      String line; 
      try { 
       while ((line = stdErr.readLine()) != null) { 
        err.write(line + newline); 
       } 
      } catch (Exception e) {throw new Error(e);} 
      try { 
       err.flush(); 
       err.close(); 
      } catch (IOException e) { /* Who cares ?*/ } 
     } 
    }.start(); // Starts now 

    // Thread that reads the std in given in input and that feeds the input of the process 
    new Thread() { 
     @Override public void run() { 
      String line; 
      try { 
       while ((line = in.readLine()) != null) { 
        stdIn.write(line + newline); 
       } 
      } catch (Exception e) {throw new Error(e);} 

      try { 
       stdIn.flush(); 
       stdIn.close(); 
      } catch (IOException e) { /* Who cares ?*/ } 
     } 
    }.start(); // Starts now 

    // Wait until the end of the process 
    try { 
     process.waitFor(); 
    } catch (Exception e) { 
     throw new Error(e); 
    } 

} // End of #communicate 

Надеюсь, это поможет.

+0

Я уже делал все это и все еще видел много этих проблем. После большого количества проб и ошибок, я думаю, что, наконец, понял: в пуле потоков закончились потоки (хотя это не должно было быть), а потоки для чтения потоков никогда не начинались. Я возьму этот вопрос на весенние форумы! (Я использую их реализацию пула потоков) Спасибо за ваш вклад! – ragstorooks

Смежные вопросы