6

I'm trying to print output and an error message to the console. but sometimes the sequence of output changes, first it prints the error message & then it prints the simple message can anybody help me understand why is it happening as such? the sequence of output changes most of the time. There is no consistency in the printed output. I'm using eclipse IDE & the output I get is as follows.

I have tried to print the following code,

System.out.println("simple message");  
System.err.println("error message");  

the expected result is this:

simple message

error message

but the actual result is this:

error message

simple message

Community
  • 1
  • 1
tushar_lokare
  • 461
  • 1
  • 8
  • 22

7 Answers7

3

System.out.println() and System.err.println() are different Streams of execution. Output Streams are cached so all the write goes into this memory buffer. After a period of quiet, they are actually written out. Here is a for loop that essentially shows your error again:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.err.println("Err");



}

In order to "flush" the Streams call .flush() each time through the loop:

for(int x = 0; x <= 5; x++) {
    System.out.println("Out");
    System.out.flush();
    System.err.println("Err");
    System.err.flush();


}

In this for loop, the out message, and the err message will initially print, but on each flush your out messages would print first, and then your err messages. The output will be something such as:

OutErr
Out
Out
Out
Out
Out

Err
Err
Err
Err
Err

And that is because System.out and System.err are executing on different Streams.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27
2

Even if you flush your streams after writing, these streams are read by different threads in Eclipse and if the writes are almost simultaneously, it happens that the thread for reading stderr is executed before the thread for stdout even if the corresponding write to stdout happened first.

Since Java 1.5 there is the ProcessBuilder class and with this it could be solved in Eclipse by redirecting stderr to stdout during launching - but Eclipse's feature to show stderr output in a different color would be broken by this.

You may add your opinion to https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205

Till Brychcy
  • 2,876
  • 1
  • 18
  • 28
  • Update: The option to merge stdout and stderr streams has meanwhile been implemented, see https://www.eclipse.org/eclipse/news/4.13/jdt.php#console-output-synchronization – Till Brychcy Jun 19 '23 at 07:13
0

Since they are two different executing streams, they execute independently. And also they aren't in different block scope so the close() is not called causing not to call flush() as well. Then they are at same level. So JVM takes the lead here and execute those two streams the way he wanted.

Therefore intentionally calling flush() at the end of each stream will help you to get back to the driving seat of your code

Indunil Aravinda
  • 793
  • 1
  • 5
  • 11
  • I have tried calling flush() after each statement,but still I'm getting the same output which is not the desired output. – tushar_lokare Jan 08 '19 at 09:31
0

try this out ..

System.out.println("Out");

 System.out.flush();

 System.err.flush();

 System.err.println(" err ");
Book Of Zeus
  • 49,509
  • 18
  • 174
  • 171
0

As suggested in previous answers you can set same stream for both output and error stream using System.setErr

System.setErr(System.out);

Reassigns the "standard" error output stream.

But this setup isn't recommended for real application in production environment

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
0
  • Remember, This is not only dependent on the user defined sequence, It is also dependent on the receiving application.
  • For example, If Eclipse IDE has two threads, one for receiving error stream and one for receiving system.out stream then those threads are not in your control and thus you may see sequence changing time to time.
  • If you are not concerned about performance then you can put some sleep in between.

System.out.println("Out");

Thread.sleep(50);

System.err.println("error");

Arpit Shah
  • 75
  • 6
0

as Simeon Ikudabo said the task is impossiple !! but for most close try this

static void print(PrintStream p, Object o) throws InterruptedException {
    Object lock = new Object();
    synchronized (lock) {

        Runnable r = new Runnable() {
            public void run() {
                synchronized (lock)
                {
                p.println(o);
                lock.notify();
                }
            }
        };
        new Thread(r).start();

        lock.wait();
    }

}

public static void main(String[] args) throws InterruptedException {

    for (int i = 0; i < 50; i++) {
        print(System.out, "out");
        print(System.err, "err");

    }}

you might see it as perfect but stil thier is a tiny teeny littel chance of getting out the race and it's not grantted too.