Exception output not coming in sequence - java

My code is as follows:
public class BoxingUnboxingExample {
public static void main(String[] args) {
Integer i1 = null;
Integer i3 = 10;
BoxingUnboxingExample b = new BoxingUnboxingExample();
b.go(i3);
b.go(i1);
}
private void go(int a){
System.out.println("a");
}
}
Now my question is:
Sometimes I get the following error message,
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
a
Whereas, I think It should always be the following,
a
Exception in thread "main" java.lang.NullPointerException
at scjp.wraperExample.BoxingUnboxingExample.main(BoxingUnboxingExample.java:12)
Am I correct?

One reason could be the exception stack trace uses standard error (System.err) to output the error data while System.out.println uses standard output (System.out).
That means both are using different mechanisms to output the data, these may not be properly synchronized.
You can also refer this earlier question.
ex

If you are in Eclipse, this is a known problem, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=32205

Output and Error are two different streams System.err and System.out.
Read this:
It is acceptable—and normal—for standard output and standard error to
be directed to the same destination, such as the text terminal.
Messages appear in the same order as the program writes them, unless
buffering is involved. (For example, a common situation is when the
standard error stream is unbuffered but the standard output stream is
line-buffered; in this case, text written to standard error later may
appear on the terminal earlier, if the standard output stream's buffer
is not yet full.)
from wikipeda
so your output stream (System.out.println) is actually buffered. Internally it calles the BufferedWriter.write() methode. take alook at this:
How System.out.println() really works

There are at least 2 effects at play here, both related to how System.out and System.err are (naturally) 2 different streams.
Buffering
System.err and System.out are both PrintStreams, which are buffered by default, however System.err is usually set to auto-flush after every write (of a byte array or whenever a newline is written).
As such, if System.err is flushed before System.out is flushed, it will appear on screen first.
The reading of those streams
In editors, it is not uncommon for both System.out and System.err to be displayed within a single console. The way this happens will influence the order in which they are displayed. Eclipse has 2 processes, one for every stream, to read from the streams and display them. The order in which they will read (and as such, display) is non-deterministic. The process that reads from System.err would have a 50% chance of being the first to receive input if both streams are written to quasi-simultanously. As such, they may appear to be randomly interleaved.

public class Main {
public static void main(String[] args) {
System.setErr(System.out); // this line seems to solve the problem
System.out.println("test");
throw new RuntimeException("Test");
}
}

Related

Why Exception log changes printed place with same code? [duplicate]

This question already has answers here:
System.out.println and System.err.println out of order
(7 answers)
Closed 9 years ago.
Please consider this java code:
public class CMain {
public static void main(String[] args){
for (int i = 0; i < 10; i++) {
System.out.println("A");
System.err.println("B");
}
}
}
By a quick look at the code, some of us may think the output has to be the print of As and Bs alternatively. However is not! It is a random appearance of 10 A characters and 10 B ones. Something like this:
Why is that? and what is the solution for it so that the As and Bs gets displayed alternatively ( A B A B A B ...)
Before I ask this question, I checked several other similar questions for solution and non worked for my case! I have brought some of them here:
Synchronization and System.out.println
Java: synchronizing standard out and standard error
Java: System.out.println and System.err.println out of order
PS. I am using Eclipse as my IDE
Why does this happen?
This is because out and err are two different output streams. However, both of them print on console. So you do not see them as different streams. Moreover, when you do out.println(), it is not guaranteed that you will see the output on the console as soon as the statement gets executed. Instead, the strings are usually(depends on the system) stored in an output buffer (if you will) which is processed later by the system to put the output from the buffer onto the screen.
Solution :(
Although, as Eng.Fouad pointed out that you can use setOut(System.err) or setErr(System.out) to make them ordered, I would still not suggest doing that when you are actually putting this in an application (only use it for debugging purposes).
What the proposed solution does is that it will end up using only one stream for both the standard output and the standard error, which I do not think is a good thing to do.
They are different OutputStreams. If you really need to guarantee the order of printing them, use:
System.setErr(System.out);
or
System.setOut(System.err);
Since there are two separate streams, the output you are giving is possible.

I would like to know how the System.err works

I am going through the Java IO. Just started with standard input and output streams. Please look at the simple program given below,
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
System.out.println("Give us your input");
String str = scanner.nextLine();
System.out.println("Standard Output: " + str);
System.err.println("Standard Error Output: " +str );
}
The output varies while running this two or three times. Please find couple of the outputs below,
Running for the first time:
Give us your input
my Name
Standard Error Output: my Name
Standard Output: my Name
Process finished with exit code 0
Running second time with the same code:
Give us your input
my Name
Standard Output: my Name
Standard Error Output: my Name
Process finished with exit code 0
I would like to know why the output changes with System.err
Your program will write to first System.out and then System.err (and println will flush these streams as well), but there is no guarantee in which order/interleaving the two streams will appear in your console.
Since you are writing to them at practically the same time, you will get both combinations. I suppose you might even get half-line interleavings.
System.out and System.err write to different streams that are connected via different pipes to your command shell. The command shell will then read from these pipes and write the data to your console application. That will ultimately write to your screen.
There are a number of places where data written to one stream could "overtake" data written to the other one.
It could possibly occur in the JVM itself, since the Java specs make no guarantees about which stream gets written first. (In fact, this is unlikely if there is only one thread doing the writing. With current Java implementations, the behavior will probably be deterministic ... though unspecified.)
It could be happening in the OS, since there are no guarantees on the order of delivery of data written to two independent pipes.
It could be happening in the shell, since nothing in the shell specs place any priority of reading from the pipes.
In short, there are lots of areas where the behavior is unspecified.
It is also worth noting that the observed behavior is liable to depend on the version of Java you use, the OS and OS tools, your hardware, and the load on your system.
Finally, there is probably nothing that you could do to guarantee that the observed interleaving (or not) are consistent. If you need consistency, write your output to one stream or the other exclusively.
no guarantee of order for System.out, System.in, System.err anything can be appeared first so order of these streams are not fixed

How to sych out and err streams in Java [duplicate]

This question already has answers here:
Java + Eclipse: Synchronize stdout and stderr
(5 answers)
Closed 8 years ago.
In the code below how can I make number printer in black and red in order we expect, like below:
1 (black)
1 (red)
2 (black)
2 (red)
as opposed to what it actually does(some random order depending on whether the err or out streams are available):
1 (black)
2 (black)
1 (red)
2 (red)
code:
package threads;
public class CThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 20; i++) {
outt(i);
err(i);
}
}
synchronized public void outt(int i){
System.out.println(i);
}
synchronized public void err(int i){
System.err.println(i);
}
public static void main(String [] org){
Thread th = new Thread(new CThread());
th.start();
}
}
Even if you try to synchronize the writing of your Streams (System.out and System.err in that case), it does not prevent that the program which is watching those Streams (Eclipse in your case) is reading those streams in that order.
There is a lot of infrastructure between that (including the OS which can sort those IO operations in whatever order it wants).
For real world applications the answer to this kind of problem is to use a logging framework. With those you can write all messages of all levels to the same file (usually in a separate thread, in the order they where logged).
If you do not want to use a logging framework and want to rely on System.out / System.err, then you cannot reliably control on how this output is being read by 3rd party applications. The only thing you can do, is to synchronize the writing of those streams by synchronizing (and flushing) the IO operations with a common lock object.
Be aware however that this technique then is a severe bottleneck to any multithreaded code.
Create an ArrayList for output and error. Instead of System.out and System.err append to that list. Then decide when you like to print it and first print an empty the output list, the print and empty the error list. The has to be synchronized. Also: New output and error coming after the ignition of the printing will not be sorted in - of course - and this cannot be solved since the output to System.out and System.err is merged in the console first come first served. If you like to solve this you have to wait until the program finishes, then print all output and all error.

Java: How to mirror console output to file

I need to monitor console output in Java, I have tried several different ways of retrieving the output as it is streamed, but I fell into a few pitfalls (looping the same output, only one part of output being captured, losing output) and have decided to go about it a different way.
I am developing a Java plugin for a server of the popular game, Minecraft, and I need to be able to monitor console output from other plugins.
I think a good way to do this is by redirecting console output to file, and then set up a recurring async task that checks the file, carries out anything it needs to do, and then clears the file for more input. I think I can do this with a simple use of System.setOut(PrintStream stream); and one of the many guides I can find on Google.
But there is a problem, and that is why I am asking here today. I need console output to stay on the console like normal, hence "mirroring". I cannot edit any of the plugins to output somewhere else, it needs to be from what my Java plugin can do and that only. Sure, maybe on every scheduled check on the file I could reprint it all back to the console but that would result in blocks being printed at a time, which would not be ideal. I do hope this is possible. Thank you!
EDIT: I don't think I explained fully. "plugins"'s classes are run by the program that I am developing for. I cannot change how classes are run and I cannot change how other plugins print to console.
I also do not want to direct console output to files for logging, that idea is only to keep it in a temporary place while it is parsed. Ideally, I need to pass each line of console output to a function (parseString(String line)) which carries out operations depending on the contents of the line. Also, I don't understand how I can read stream contents line-by-line properly, so if someone has any idea on how to, please let me know. :)
Capture System.out before changing it, and use TeeOutputStream:
OutputStream myCaptureStream = ...;
PrintStream original = System.out;
OutptStream outputtee = new TeeOutputStream(originalOut, myCaptureStream);
PrintStream printTee = new PrintStream(outputTee);
System.setOut(printTee);
Convert output stream (myCaptureStream) to an input stream
Use Java standard library PipedOutputStream: new PipedOutputStream; read carefully - you'll need your reader running on another thread.
Convert the input stream to a Reader,
and that to a BufferedReader.
BufferedReader gives you a readLine method.
Pseudo code:
// Feed myCaptureStream to TeeOutputStream
OutputStream myCaptureStream = new PipedOutputStream();
// Prepare to capture data being written to that output stream
InputStream myCaptureAsInputStream = new PipedInputStream(myCaptureStream);
Reader myCaptureReader = new InputStreamReader(myCaptureAsInputStream);
BufferedReader myCaptureBuffered = new BufferedReader(myCaptureReader, 1024);
// This must run on separate reader thread; in spin loop:
myCaptureBuffer.readLine
You can change the System.out and System.err to be references to your own custom PrintStreams. This solution is cross platform, unlike using a platform specific helper executable such as tee.
Documentation for System.setOut(PrintStream)
You can write your own PrintStream Subclass that looks something like:
class MirroringPrintStream extends PrintStream
{
PrintStream first, second;
public MirroringPrintStream(PrintStream first, PrintStream second)
{
// fail now rather than later
if (first == null || second == null) throw new NullPointerException();
this.first = first;
this.second = second;
}
#override
// methods go here (I do believe there are rather a lot of them, but they will all look the same)
}
You can then use System.setOut(new MirroringPrintStream(System.out, myLogStream)) where myLogStream is the PrintStream you opened to your log file. I'm not sure how this will handle appending to a file that something else periodically truncates, you might want to experiment with that a bit.
All else fails, go to irc.esper.net and ask about it in #risucraft
Assuming this is a friendly takeover of console output, why not log to your own stream
and mirror that to the console?

Java reading standard output from an external program using inputstream

I am trying to develop a class that reads the standard output of an external program(using an instance of Process, Runtime.getRuntime().exec(cmdLine, env, dir)).
The program takes user inputs during the process, and would not proceed until a valid input is given; this seems to be causing a problem in the way I am trying to read its output:
egm.execute(); // run external the program with specified arguments
BufferedInputStream stdout = new BufferedInputStream(egm.getInputStream());
BufferedInputStream stderr = new BufferedInputStream(egm.getErrorStream());
BufferedOutputStream stdin = new BufferedOutputStream(egm.getOutputStream());
int c; //standard output input stream
int e; //standadr error input stream
while((c=stdout.read()) != -1) //<-- the Java class stops here, waiting for input?
{
egm.processStdOutStream((char)c);
}
while((e=stderr.read()) != -1)
{
egm.processStdErrStream((char)e);
}
//...
How can I fix this so that the program takes in a valid input and proceed? Any help resolving this problem will be great!
You have to consume both the program's stdout and stderr concurrently to avoid blocking scenarios.
See this article for more info, and in particular note the StreamGobbler mechanism that captures stdout/err in separate threads. This is essential to prevent blocking and is the source of numerous errors if you don't do it properly!
In this situation you should have separate Threads reading InputStream and ErrStream.
Also you may want to do something like:
public void run() {
while( iShouldStillBeRunning ) {
int c;
while( stdout.available() > 0 && ((c=stdout.read()) != -1)) {
egm.processStdOutStream((char)c);
}
Thread.sleep(100);
}
}
Because you will get blocked on stdout.read() until there is input.
For one thing, this may block if it's writing to the error stream and has exhausted the buffer - you're not reading from the error stream until the output stream has completely finished.
Next, you say it takes user input during the process - are you giving it any user input by writing to stdin? If it's waiting for input, you should write to stdin appropriately, and flush it.
You're not saying in your question what is actually happening when you try to run this. Please update with a detailed description of what happens, and what you would expect to happen instead. Bonus points for telling us what the command is.
Also, is this UNIX/Linux or Windows? If this is UNIX/Linux (or some other POSIX platform), the program may be looking for input on /dev/console instead of /dev/stdin for security reasons.
For the benefit of others looking for solutions to this type of problem I just want to add that I had a very similar problem. But in my case the program was also waiting for a single line of input. So there need to be three threads involved to asynchronously handle all three channels.
Without writing to the output (i.e. the stdin of the executing program) caused the input (i.e. the output from the executing program) not to be captured completely. Writing to it hanged the process.
The solution was the three words by Jon Skeet: "and flush it". After adding the flush, no hang. Thanks!

Categories