나는 웹을 이미 검색했으며, 질문은 process.waitFor() never returns으로 표시되어 stdout 또는 stderr이 읽지 않는 프로세스에서 종종 문제가 있음을 나타냅니다.Process.waitFor stdout과 stderr이 읽히더라도 응답하지 않는다
우리는 이것을 달성하기 위해 redirectOutput
및 redirectError
와 ProcessBuilder
를 사용하고, 나는 우리가 우리가 프로세스를 실행하는 데 사용할 다음과 같은 방법을 참조하십시오 안전을해야한다고 생각 : 아직
public static void execute(String directory, long timeout, File out, File err, String... command) throws InterruptedException, IOException {
LOGGER.log(Level.INFO, String.format("executing command %s (%s)", Arrays.toString(command), timeout > 0 ? String.format("timeout = %,d[ms]", timeout) : "no timeout"));
ProcessBuilder builder = new ProcessBuilder();
builder.directory(new File(directory));
builder.command(command);
builder.redirectOutput(out);
if(out == err) {
builder.redirectErrorStream(true);
} else {
builder.redirectError(err);
}
long time = System.currentTimeMillis();
Process process = builder.start();
try {
LOGGER.log(Level.FINE, "waiting for process");
boolean exited = process.waitFor(timeout, TimeUnit.MILLISECONDS);
if(!exited) {
LOGGER.log(Level.WARNING, "timeout reached, trying to destroy ...");
exited = destroy(silent, process); // Helper method to destroy processes
}
long duration = System.currentTimeMillis() - time;
int exitValue = process.exitValue();
LOGGER.log(Level.INFO, "execution finished in " + duration + "[ms] => " + exitValue);
} catch (InterruptedException | Error | RuntimeException e) {
LOGGER.log(Level.SEVERE, "execution failed", e);
throw e;
}
}
를 문제가 있다는 것입니다 프로세스가 시간 초과 내에서 쉽게 끝났음에도 불구하고 process.waitFor(timeout, TimeUnit.MILLISECONDS)
호출에 응답하지 않습니다.
로깅 출력된다
Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute
INFO: executing command [java, -Xmx8G, -XX:+UseG1GC, -XX:+CrashOnOutOfMemoryError, -jar, MetricCalc.jar] (timeout = 14,400,000[ms])
Oct 07, 2017 12:39:55 AM at.ProcessExecutor execute
FINE: waiting for process
err
파일
... Things we write to std.err ...
Finished Metrics
를 판독 MetricCalc의 주요 방법
같다 (단execution finished
라인이 아직 기록되지 않은 것을 인식)
public static void main(String[] args) {
.... do some stuff ...
System.err.println("Finished Metrics");
}
읽기가 제대로 작동 함을 나타내면 Java 프로그램의 마지막 행이 실행되고 프로세스가 종료되어야합니다.
프로세스가 종료되지 않는 이유를 알고있는 사람은 누구나 Process.waitFor()
에 계속 응답합니까?
* ".... 프로세스가 종료되어야합니다."* - 하위 프로세스가 예상대로 작동한다고 가정합니다. 자식 프로세스가 실제로 종료되었는지 확인하십시오. 예 : "ps -efl"또는 유사한 것을 사용하십시오. –
@StephenC : 나는 아직도'ps -efl | grep "java -Xmx8G"', 종료되지 않았 음을 나타냅니다. 그러나 MetricCalc (프로세스로 실행되는 Java 프로그램) 코드의 마지막 줄이 실행 된 이후로 이것이 왜 그런지는 잘 모릅니다 ... –
오, 그냥 내 마음에 왔을 것입니다 : 아마도 MetricCalc 비 데몬 (non-deamon) 쓰레드가 실행 중이다. 이로 인해 애플리케이션이 종료되는 것을 막을 수있다. –