我有一个应用程序在我的PC的指定位置调用java测试类。该路径现在是硬编码的,我通过从命令行执行它检查它是否有效(如果你想看到它:java -cp C:\Users\user\Documents\workspace\test\build\test.jar org.junit.runner.JUnitCore us.test.DynamicWebserviceInvocationTest
),所以我知道命令工作正常。
问题是,当我执行Runtime.getRuntime().exec(command)
时,如果我尝试记录其生成的进程的结果InputStream和ErrorStream,程序就会卡住。我尝试使用exitValue()和waitFor(),但是第一次抛出了一个不完整的错误而第二次也被卡住了。奇怪的是,如果我不接触任何内容(流,或使用函数),程序没有问题结束。
所以我的问题是:为什么会这样?下一步是用给定的参数构建命令,但是如果我看不到结果输入我就不能完全确定测试是否正在运行。
代码,如果你想看到它:
Runtime runtime=Runtime.getRuntime();
logger.debug("Attempting to execute the test {} at path {}",classpath,applicationLocation);
String command="java -cp C:\\Users\\user\\Documents\\workspace\\test\\build\\test.jar org.junit.runner.JUnitCore us.test.DynamicWebserviceInvocationTest";
Process process=runtime.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
答案 0 :(得分:1)
你绝对必须在不同的线程中读取两个流。 (阅读Process类的Javadoc)。如果等待结束,或者在另一个之前读取第一个流,则可能发生命令的输出缓冲区填满并且它将阻塞(在stdout或stderr上,具体取决于您首先读取的内容)。通常你在当前线程中使用waitFor()并使后台线程耗尽输出(这也允许检测子进程的结束而不进行轮询)。
如果您只想使用一个(附加)线程,可以将stderr重定向到stdout。如果你想避免阅读流,你可以设置 ProcessBuilder功能inheritIO()。这允许将流写入现有输出,因此您不需要独立读取线程。
有各种各样的图书馆提供exec工具(例如Apache Commons Exec has some streams),它们为Process
提供活跃的流排放,记录或抽取。
除此之外,如果命令等待输入,首先关闭stdin可能也是个好主意:p.getOutputStream().close();
答案 1 :(得分:0)
确保关闭2个流:
String command="java -cp C:\\Users\\user\\Documents\\workspace\\test\\build\\test.jar org.junit.runner.JUnitCore us.test.DynamicWebserviceInvocationTest";
Process process=runtime.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
stdInput.close();
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
stdError.close();