Redirect System.Out.Println

Redirect System.out.println

The System class has a setOut and setErr that can be used to change the output stream to, for example, a new PrintStream with a backing File or, in this case, probably another stream which uses your logging subsystem of choice.


Keep in mind you may well get yourself into trouble if you ever configure your logging library to output to standard output or error (of the infinite recursion type, possibly).

If that's the case, you may want to just go and replace your System.out.print-type statements with real logging calls.

Redirect System.out.println to log

My suggestion would be to refactor if possible.
For a possible solution, check these similar questions

log4j redirect stdout to DailyRollingFileAppender

Redirect System.out.println to Log4J, while keeping class name information

Redirect System.out and System.err

Just to add to Rick's and Mikhail's solutions, which are really the only option in this scenario, I wanted to give an example of how creating a custom OutputStream can potentially lead to not so easy to detect/fix problems. Here's some code:

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import org.apache.log4j.Logger;

public class RecursiveLogging {
/**
* log4j.properties file:
*
* log4j.rootLogger=DEBUG, A1
* log4j.appender.A1=org.apache.log4j.ConsoleAppender
* log4j.appender.A1.layout=org.apache.log4j.PatternLayout
* log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
*
*/
public static void main(String[] args) {
// Logger.getLogger(RecursiveLogging.class).info("This initializes log4j!");
System.setOut(new PrintStream(new CustomOutputStream()));
System.out.println("This message causes a stack overflow exception!");
}
}

class CustomOutputStream extends OutputStream {
@Override
public final void write(int b) throws IOException {
// the correct way of doing this would be using a buffer
// to store characters until a newline is encountered,
// this implementation is for illustration only
Logger.getLogger(CustomOutputStream.class).info((char) b);
}
}

This example shows the pitfalls of using a custom output stream. For simplicity the write() function uses a log4j logger, but this can be replaced with any custom logging facility (such as the one in my scenario). The main function creates a PrintStream that wraps a CustomOutputStream and set the output stream to point to it. Then it executes a System.out.println() statement. This statement is redirected to the CustomOutputStream which redirects it to a logger. Unfortunately, since the logger is lazy initialized, it will acquire a copy of the console output stream (as per the log4j configuration file which defines a ConsoleAppender) too late, i.e., the output stream will point to the CustomOutputStream we just created causing a redirection loop and thus a StackOverflowError at runtime.

Now, with log4j this is easy to fix: we just need to initialize the log4j framework before we call System.setOut(), e.g., by uncommenting the first line of the main function. Luckily for me, the custom logging facility I have to deal with is just a wrapper around log4j and I know it will get initialized before it's too late. However, in the case of a totally custom logging facility that uses System.out/err under the cover, unless the source code is accessible, it's impossible to tell if and where direct calls to System.out/err are performed instead of calls to a PrintStream reference acquired during initialization. The only work around I can think of for this particular case would be to retrieve the function call stack and detect redirection loops, since the write() functions should not be recursive.

Redirecting System.out.print(ln) to a textArea

Swing is a single threaded framework, this means that any operation which is run within the context of the Event Dispatching Thread, which is long running in nature or blocks for some reason (like I/O operations), will prevent the EDT from processing new events and update the UI.

See Concurrency in Swing for more details

If you're using something like How to set output stream to TextArea to redirect the System.out, then you could safely wrap the decryption process in some thing like a SwingWorker or other Thread, for example...

public class DecryptWorker extends SwingWorker {

private File[] files;

public DecryptWorker(File[] files) {
this.files = files;
}

@Override
protected Object doInBackground() throws Exception {
if(files[0] != null) {
...
for (int j = 0; j < files.length; j++) {
// SDencryptFiles() has System.out.println()'s in it, but
// no System.out's show in the JScrollPane until after
// SDencryptFiles completes I want then to appear as they
// are executed
SDencryptFiles(String, String, int);
}
}
return null;
}

}

See Worker Threads and SwingWorker for more details...

Redirect console output to string in Java

If the function is printing to System.out, you can capture that output by using the System.setOut method to change System.out to go to a PrintStream provided by you. If you create a PrintStream connected to a ByteArrayOutputStream, then you can capture the output as a String.

Example:

// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
// IMPORTANT: Save the old System.out!
PrintStream old = System.out;
// Tell Java to use your special stream
System.setOut(ps);
// Print some output: goes to your special stream
System.out.println("Foofoofoo!");
// Put things back
System.out.flush();
System.setOut(old);
// Show what happened
System.out.println("Here: " + baos.toString());

This program prints just one line:

Here: Foofoofoo!

Redirect lots of system.out.println's to a .txt file

The System class has a static method, System.setOut(PrintStream out). All you have to do is create your own PrintStream that writes to a file, stuff it into this method and you're all set.

Better less fragile solution: Don't use System.out.printFoo(...) but instead just use a logger, and change the logging levels as it suits your purposes at that time.



Related Topics



Leave a reply



Submit