0

我创建了一个包含 2 个 Jar 文件的 Java 应用程序。Jar1 用于初始化和运行 Jar2,使用以下代码:

Process process = runtime.exec( "java -jar Jar2.jar" );
printLogs( process );
.
.
.
private static boolean printLogs( Process process ) {
    try {
        BufferedInputStream logStream = new BufferedInputStream( process.getInputStream() );
        String logs = "";
        int buffer = 0;

        while ( ( buffer = logStream.read() ) != -1 ) {
            logs += (char)buffer;
        }

        if( !logs.isEmpty() ) logger.debug( logs );
    } catch (IOException e) {}  

    return true;
}

我使用 Log4J 从 Jar2 打印许多日志,即

logger.debug( "..." );

但是 Jar2 中的日志都没有打印到控制台。我发现这是因为日志返回到 Jar1 而不是控制台,所以我使用上面的代码打印了返回流。现在可以很好地打印日志,但是在所有 Jar2 进程结束之后,所有日志都会在 Jar1 中一次打印。

问题是:我可以及时打印 Jar2 中的每个日志行,而不是等待所有 Jar2 进程结束吗?

因为 Jar2 是一个漫长的过程,我可以在应用程序处理时看到这些日志,这一点很重要。

4

3 回答 3

2

整个事情非常混乱。你不应该需要两个单独的档案和Runtime.exec()

但是,通常用于BufferedReader.readLines阅读文本行。请注意,如果您在阅读时记录每一行,问题就会消失:

BufferedReader input = new BufferedReader(
  new InputStreamReader(process.getInputStream())
);
String line = null;

while ((line = input.readLine()) != null) {
  System.out.println(line);
}

您的代码等待子进程完成,因为您在流结束后记录了该行(即在子进程终止后)

这是一个演示程序,它使用一个长时间运行的 Ruby 程序作为监视进程

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Subprocess {

    static final String[] program = new String[] {
        "ruby",
        "-e" ,
        "(1..5).each{|i|sleep 1;puts i;STDOUT.flush}"
    };

    public static void main(String[] args) throws IOException {
        ProcessBuilder builder = new ProcessBuilder(program);
        builder.redirectErrorStream();

        Process child = builder.start();

        String line = null;
        BufferedReader in = new BufferedReader(
                new InputStreamReader(child.getInputStream()));

        while ((line = in.readLine()) != null)
            System.out.println(line);
    }

}
于 2012-09-18T12:33:08.580 回答
0

您的代码似乎在等待实际写入日志之前logStream到达EOF(在进程退出时发生)。尝试重构它以逐个字符地读取它,然后在您看到换行符时记录累积的字符缓冲区(EOF当然还有 ,所以您会得到最后一行)。

于 2012-09-18T12:24:31.217 回答
0

在这篇文章的帮助下,我能够解决这个问题:

读取 system.in 时,Runtime.exec 永远不会返回

我也使用过ProcessBuilder

于 2012-09-22T17:15:12.053 回答