JavaSoft's VM uses native methods to modify the public static final
System.in, .out, and .err fields. The java-linux port has a modified
System.java which uses the inner-class DelegatingPrintStream to get around
this, but causes an incompatibility between code based on the behavior of
Sun's VM and Linux's. 

I got around the problem by editing and compiling my own
java.lang.System, making in, out, and err non-final fields, and
changing their initialization & set methods.

I've attatched the sample code that breaks the java-linux System class if
you want to look at it.

BTW: I agree with the author of DelegatingPrintStream et al. that this was
a terrible way of implementing public-read/private-write on the part of
Sun.

Cest la vie...

Joshua Pollak
http://www.pico.org/~josh

On Mon, 11 May 1998, Albert L. Ting wrote:

> Joshua Pollak writes:
> > From: Joshua Pollak <[EMAIL PROTECTED]>
> > To: [EMAIL PROTECTED]
> > Subject: java.lang.System$DelegatingPrintStream
> > Date: Mon, 4 May 1998 13:04:08 -0400 (EDT)
> > 
> > 
> > It looks like the intent of "DelegatingPrintStream" is to cause all
> > references to System.out to point to the current System.out even if the
> > user reassigns System.out. Unfortunately, this is contrary to the behavior
> > of Sun's API.
> > 
> > I'd be interested in hearing why there are diferences between Sun's
> > classes.zip and the one distributed with JDK 1.1.5 for Linux.
> > 
> > FYI, this breaks the logging code in our software.
> > 
> > Thanks for your attention (and great work in porting the JDK).
> > 
> > -josh
> 
> Hi Josh,
> 
>    Did you get a response?  I'm having the same problem with jdk1.1.5.
> 
> Thanks,
> Albert
> 
> -- 
> Albert L. M. Ting * [EMAIL PROTECTED] * 408-548-3111 * http://www.artisan.com
> Artisan Components, Inc. * 1195 Bordeaux Drive * Sunnyvale, CA  94089 * USA
> 

here's the code that breaks under java-linux:


import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;

public class Redirect extends OutputStream {

  OutputStream out1;
  OutputStream out2;

  public Redirect(OutputStream out1,
                  OutputStream out2) {
    this.out1 = out1;
    this.out2 = out2;
  }

  public void write(int c) throws IOException {
    out1.write(c);
    out2.write(c);
  }

  public static void main(String[] args) throws Exception {
    OutputStream console = System.out;
    OutputStream file = new FileOutputStream("file");
    Redirect r = new Redirect(console, file);

    PrintStream ps = new PrintStream(r);
    System.setOut(ps);

    console.write("This should go to the console only.\n".getBytes());
    console.flush();

    file.write("This should go to the file only.\n".getBytes());
    file.flush();

    ps.print("This should go to the console and file.\n");
    ps.flush();

  }

}


Reply via email to