确定是否已成功完成另一个Java应用程序的java执行

时间:2015-04-28 21:01:56

标签: java testing logging execute

我有一个应用程序在我的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);
}    

2 个答案:

答案 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();