I already have a java program using log4j to write output on console, while now I want use another java program to invoke the first one(sub-process) and intercept its output.
I use the method in this page http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4, some codes like below
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>
I can get the output message, but just in “run.bat” using echo XXX , not the message generated by log4j. If I run “run.bat”, I can see both the output in console. Is there a way that I can also get the log4j output in parent process? thanks.
The
StreamRedirectorextendsThreadbut you callrunnotstart. This means thatrunis getting called synchronously, in the calling thread. Which means that in the followingThe second line does not execute until the first completes. I guess if the error stream does not produce much output then it will eventually complete. But is that really what you intend to do? Instead try
If the program is using
log4jI urge you to considerSocketAppenderto grab what is written to it from a different process.EIDT: Another approach is for
StreamRedirectorto extendRunnableinstead ofThread. The calling code then changes toThis won’t prevent you from calling
errorThread.run()but if you do call it then it will return immediately (instead of blocking as it currently does) suggesting that something is wrong.