extrange behaviour

F

Federico

Hello,

I can't understand something:
Java has System.out and System.err. I want both to go to the same pipe,
so I, succesfully, do this:
System.setErr(System.out);
(now System.err is redirected to System.out). This works fine. But if
after doing this, I redirect the System.out to a file, it no longer
works, even if I do again "System.setErr(System.out)". Look at the code:

System.setErr(System.out); //this works.
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err never
goes to the file I created.
} etc, etc...


Any help? do you know why it is not working?
Thanks in advance,
Federico
 
T

Tony Morris

There is a reason why it isn't working.
Here's a hint:
Why is System.out/err declared final, yet you can modify them with
setOut/setErr?
Note that you can't modify a final with reflection pre-J2SE 5.0 (this is a
separate issue).
 
F

Federico

I didn't understand you, sorry. I'm not an experte in java (not a
newbie, neither).
I still don't understand why if System.err is redirected to System.out
(it works), and .out to a file (it works), why .err don't go to the file.
 
F

Federico

sorry, I forgot to add a line to the "problematic" code:

System.setErr(System.out); //this works.
opts.output = new PrintWriter(System.out, true); //Missing line
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err
//never goes to the file I created.
} etc, etc...
 
O

Oscar kind

Federico said:
I can't understand something:
Java has System.out and System.err. I want both to go to the same pipe,
so I, succesfully, do this:
System.setErr(System.out);
(now System.err is redirected to System.out). This works fine. But if
after doing this, I redirect the System.out to a file, it no longer
works, even if I do again "System.setErr(System.out)". Look at the code:

System.setErr(System.out); //this works.
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err never
goes to the file I created.
} etc, etc...

Is System.out redirected? According to the code you posted, you only
redirect System.err to System.out...
 
F

Federico

Oscar said:
Is System.out redirected? According to the code you posted, you only
redirect System.err to System.out...


Sorry, you are right, I corrected the code in the other message. The
code is:
System.setErr(System.out); //this works.
opts.output = new PrintWriter(System.out, true); //Missing line
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err
//never goes to the file I created.
} etc, etc...

Thanks,
Federico
 
O

Oscar kind

Federico said:
I corrected the code in the other message. The code is:
System.setErr(System.out); //this works.
opts.output = new PrintWriter(System.out, true); //Missing line
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err
//never goes to the file I created.
} etc, etc...

Here you create a PrintWriter, opts.output, that writes to System.out.
Later you change it to a PrintWriter that writes to a file.

There is however, no call to System#setOut(PrintStream) to redirect
System.out (as you do for System.err).
 
J

John C. Bollinger

Federico said:
sorry, I forgot to add a line to the "problematic" code:

System.setErr(System.out); //this works.
opts.output = new PrintWriter(System.out, true); //Missing line
try {
//open the PrintWriter with file
FileOutputStream fo = new FileOutputStream(output_file);
opts.output = new PrintWriter(fo, true);
System.setErr(System.out);
//with or whitout this line, it doesn't work, the System.err
//never goes to the file I created.
} etc, etc...

Aha. That clears it up. Here's what is happening:

() You redirect error output to System.out.

() You create a PrintWriter wrapping System.out, and assign a reference
to it to variable opts.output. Note that output to System.err will
_not_ go through this writer, but rather straight to System.out.

() You create a PrintWriter wrapping a FileOutputStream and assign a
reference to _that_ to variable opts.output, replacing the previous
value. The new writer has nothing whatsoever to do with System.out or
System.err. At this point there are no more live references to the
PrintWriter you created at the previous step (around System.out), so
it's eligible for GC.

() You redirect error ouptut to System.out, which has no effect because
System.err is already directed there.


There are two main options by which you may want to proceed:
(1) Handle I/O redirection external to Java. I.e. from a Unix command
prompt you could do "java mypackage.MyProgram 1> output_file 2>
output_file". You could do the same in Windows, except that the Windows
command interpreter doesn't seem to allow you to redirect both stdout
and stderr at the same time. (If anyone knows how to accomplish this
feat in Windows then I'd be interested to hear about it.)

(2) If you want to send output to a custom configured stream then pass
around the appropriate stream and use it directly instead of System.out
and System.err.

If you have a large body of existing code that you are trying to adapt,
and if (1) is not a viable option, then you can
System.setErr(System.out), as you did, and just write to System.out
everywhere. If either of those conditions does not apply then you are
better off with (1) or (2).


John Bollinger
(e-mail address removed)
 
J

Jochen Deyke

John said:
There are two main options by which you may want to proceed:
(1) Handle I/O redirection external to Java. I.e. from a Unix command
prompt you could do "java mypackage.MyProgram 1> output_file 2>
output_file". You could do the same in Windows, except that the Windows
command interpreter doesn't seem to allow you to redirect both stdout
and stderr at the same time. (If anyone knows how to accomplish this
feat in Windows then I'd be interested to hear about it.)


java mypackage.MyProgram > output_file 2>&1

works for me on windows XP.
 
F

Federico

Oscar kind said:
Here you create a PrintWriter, opts.output, that writes to System.out.
Later you change it to a PrintWriter that writes to a file.

There is however, no call to System#setOut(PrintStream) to redirect
System.out (as you do for System.err).

umm... you are right, there was no extrange behaviour, it was my fault
(so obvious now, so obscure before)

Thanks,
Federico
 
F

Federico

And thanks also to the other people who answered. The problem was that
I wasn't redirecting System.out to the file (I tought I was doing so).

thanks,thanks,thanks,
Federico
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,679
Members
48,796
Latest member
Greg L.

Latest Threads

Top