我已经有一个java程序使用log4j在控制台上写输出,而现在我想使用另一个java程序来调用第一个(子进程)并拦截其输出。 我使用此页http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4中的方法,有些代码如下
class StreamRedirector extends Thread
{
InputStream is;
StreamRedirector(InputStream is)
{
this.is = is;
}
public void run()
{
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line=null;
while ( (line = br.readLine()) != null)
{
System.out.println(line);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
.............
try
{
Process p = Runtime.getRuntime().exec("run.bat");
StreamRedirector errSR = new StreamRedirector(p.getErrorStream());
StreamRedirector outSR = new StreamRedirector(p.getInputStream());
errSR.run();
outSR.run();
int exitVal = p.waitFor();
System.out.println("Exit Value: " + exitVal);
}
log4j config:
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%t] [%c{1}] %m%n" />
</layout>
</appender>
我可以使用 echo XXX 获取输出消息,但只能在“run.bat”中,而不是log4j生成的消息。如果我运行“run.bat”,我可以在控制台中看到两个输出。有没有办法让我在父进程中获得log4j输出?感谢。
答案 0 :(得分:1)
StreamRedirector
延伸Thread
,但您致电run
而非start
。这意味着在调用线程中同步调用run
。这意味着在以下
errSR.run();
outSR.run();
第二行在第一行完成之前不会执行。我猜如果错误流没有产生太多输出,那么它最终会完成。但这真的是你打算做的吗?而是尝试
errSR.start();
outSR.start();
如果程序正在使用log4j
,我建议您考虑SocketAppender
从其他进程中获取写入的内容。
EIDT:另一种方法是StreamRedirector
扩展Runnable
而不是Thread
。然后调用代码变为
Thread errorThread = new Thread(new StreamRedirector(p.getErrorStream()));
....
errorThread.start();
这不会阻止你调用errorThread.run()
,但是如果你确实调用了它,那么它会立即返回(而不是像目前那样阻塞),这表明出现了问题。