Reputation: 327
I have troubles understanding this;
public static void main(String[] args){
int nulberOfTests = 10;
for( int i=0 ; i < numberOfTest ; i++){
try{
File file = getRandomFile(directory);
foo(file);
}catch(IOException){
System.out.println("Failed to split the file: " + file.getName());
}
}
}
foo(File file) throws IOException{
System.out.println("Starting foo with " +file.getName());
List<String> blockFiles = split(file); //this throws IOException.
for(int i =0 ; i< blockFiles.size(); i++){
try{
bar(blockFiles.get(i)); //this throws some exceptions
}catch (Exception e){
System.err.println("Failed bar on " + blockFiles.get(i));
e.printStackTrace();
//Handle the exception
}finally{
//clean up
}
}
//continue with the function
}
In my mind it is so: i launch a foo; it try to plit the file; if it fails, it throws IOException and i just write it and continue with another foo(file) (with another file). This is working as expected.
If it works, then i have a list of blockFiles names, and i go in the other loop to run bar on each blockFiles. If a bar fails, then i handle the exception, clean up the stuff, and continue the loop with the next blockfile.
However, what happens is: it start to handle the exception and at the same time, start another foo with another file. I can have an output like this:
Starting foo with file7
Failed bar on file7.block3
Starting foo with file12
Java.lang.NullPointerException
....
So the printStackTrace happens AFTER the next foo start. And i don't understand this. It should just continue with the loop of bar functions and with the rest of foo, before going back to main loop and starting another foo.
Can someone explain me this weird behavior? And maybe tell me what to change so that everything in the catch run before another foo start?
PS: I know this is not "Minimal Complete and Verifiable", but there is just too much stuff in this to makes it complete and verifiable, and it would have been really harder to understand. I hope what's here will be enough.
Upvotes: 2
Views: 62
Reputation: 3817
The accepted answer is incorrect or at least ambiguous.
If you substitute the System.err with a System.out the order of the two println will be the same: the error and then the start of the new file.
What is out of order is the stack trace.
The reason is the same. The method java.lang.Throwable.printStackTrace() writes on the System.err.
If you want the order that you expect, print the stack trace and the messages in the same stream.
To print the stack trace on the System.out, use:
e.printStackTrace(System.out);
java.lang.Throwable.printStackTrace()
Upvotes: 0
Reputation: 718698
Your question is very hard to understand, and the code is clearly not real, but I think you are asking why the messages are being displayed in an unexpected order.
One possible answer is this:
System.out.println("Failed to split the file: " + file.getName());
System.out.println("Starting foo with " +file.getName());
System.err.println("Failed bar on " + blockFiles.get(i));
e.printStackTrace();
Did you notice that some of those print to System.out
, and others to System.err
?
Those are two distinct streams. Even if they are redirected to the same place, within Java the two streams are buffered separately and have different "autoflush" characteristics. This means that the output is liable to be interspersed in unexpected ways. For example:
public static void (String[] args) {
System.out.println("Hi");
System.err.println("Mom");
}
Might output:
Hi
Mom
or
Mom
Hi
If you need your error messages or stacktraces to appear in the order your code writes them, just use ONE stream for the messages.
Upvotes: 2