   [java] Console redirect + multithreading
  so i redirected the console to a pipe and used the pipe to create a buffer reader to display System.out.println() calls in a swing graphics console, this works fine except for multi threading.iv looked on a few java forums and apparently its a known bug pipes break if you use them in another thread and close that thread, though for some reason a un-redirected console doesn't have this problem.so in all those forums i've yet to find a working solution and was wonder if anyone else has had a similar problem, i would have though redirecting console prints and errors would be fairly common for graphical application.   
  Java comes with integrated logging package. There's also Log4j, the de-facto standard logging framework.Learn it. Love it. Use it.Console output in Java is sign of legacy code.   ;Quote:Original post by AntheusConsole output in Java is sign of legacy code.and claiming console output is outdated is narrowminded.   ;Quote:Original post by capn_midnightQuote:Original post by AntheusConsole output in Java is sign of legacy code.and claiming console output is outdated is narrowminded.I'm pretty sure he meant as a means of logging.  Though I must confess that I still use the console for debug output while developing the code.   ;  i'll read up on java logging but right now im just making a simple application and i don't want a overly complicated solution, i just want a easy way to get the statues and errors of the application moduals into a graphical interface.   ;  I wouldn't use System.out.println() for my logging messages (though it's convenient to redirect). I would try something like this:Create a Logger class that has different methods for logging (debug, warning, error, fatal, etc). This class has a reference to your TextArea (or whatever control you are using). Whenever a call comes in, append that message to the TextArea. JTextArea.append() is thread safe, so you shouldn't have any problems there.That's the easiest approach, I think.   ;  i will do something like that if i have to but i would like to avoid creating any dependencys on the individual moduals or having to pass a object reference to all of them   ;  Here is a simple example using Java's Logging class.  The only thing you need to do is use the same name for the logger.  There is no need to pass around objects...import java.util.Random;import java.util.logging.Handler;import java.util.logging.LogRecord;import java.util.logging.Logger;public class ConsoleLogger extends Handler {  class MyThread extends Thread {    private String name;    public MyThread( String name ) { this.name = name;    }    public void run() { for( int i = 0; i < 10; ++i ) {   try {long sleep = new Random().nextInt( 100 );Logger.getLogger( "any.name.here" ).info(name + "(" + i + "): Sleep(" + sleep + ")"   );  Thread.sleep( sleep );} catch( Exception e ) {} }    }  }  public ConsoleLogger() {    // redirect logger to use custom handler...    Logger log = Logger.getLogger( "any.name.here" );    log.setUseParentHandlers( false );    log.addHandler( this );    // create new threads    // Notice we are not passing around and logging objects!    MyThread t1 = new MyThread( "T1" );    MyThread t2 = new MyThread( "T2" );    MyThread t3 = new MyThread( "T3" );    // start thread...    t1.start();    t2.start();    t3.start();    // wait for threads to stop...    try { t1.join(); t2.join(); t3.join();    } catch( InterruptedException e ) { }  }  public void close() throws SecurityException {    // override for Handler  }  public void flush() {    // override for Handler  }  public void publish( LogRecord record ) {    System.out.println( "Custom Log Record!!!" );    System.out.println( "  " + record.getMessage() );  }  public static void main( String[] args ) {    new ConsoleLogger();  }};  java.lang.Thread already has a name. class MyThread extends Thread {    public MyThread( String name ) { super(name);    }    public void run() { for( int i = 0; i < 10; ++i ) {   try {long sleep = new Random().nextInt( 100 );Logger.getLogger( "any.name.here" ).info(getName() + "(" + i + "): Sleep(" + sleep + ")"   );  Thread.sleep( sleep );} catch( Exception e ) {} }    }  }You can even go further than that:  public void publish( LogRecord record ) {  // You need to construct message in a buffer, since publish  // System.out can be used elsewhere, and would result in interleaved messages  StringBuffer sb = new StringBuffer();  sb.append( "Custom Log Record!!!  " );  sb.append( Thread.currentThread().getName() ); // <--  sb.append( " " );  sb.append( record.getMessage() );  System.out.println( sb );  }But implementing Handler is "The Right Way" to do this in Java.To log into some Swing component, you'd just provide your custom Handler to do that - the rest of your application remains the same.   ;Quote:Original post by Antheusjava.lang.Thread already has a name.Yep.  You're right.  Thats better than mine.  [cool]Either way, it is easy to add the custom logging for whatever you need.Kaze - Hope this helps.Antheus - Thanks for the refactoring!!!