Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In case of Error, program shows unexpected behavior [duplicate]

Tags:

java

try-catch

I was just trying something with try-catch and this code:

public class MainThread
{
    public static void main(String [] args) 
    {
        try 
        {
            badMethod();  
            System.out.print("A"); 
        }  
        catch (Exception ex) 
        {
            System.out.print("B");  
        } 
        finally 
        {
            System.out.print("C"); 
        } 
        System.out.print("D"); 
    }  
    public static void badMethod() 
    {
        throw new Error(); /* Line 22 */
    } 
}

I understand Error will not be caught by the catch block above, but the finally block will be executed, and then the JVM will terminate.

But when I try to run the program many times, I get different outputs:

C printed before the stack trace:

CException in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)

or C printed after the stack trace:

Exception in thread "main" java.lang.Error
  at MainThread.badMethod(MainThread.java:22)
  at MainThread.main(MainThread.java:7)
C

Can anyone explain this behavior?

like image 574
codingenious Avatar asked Oct 28 '13 14:10

codingenious


2 Answers

The System.out stream and the System.err stream are separate streams which both have the same output. As such there is a race between them and which "wins" cannot be determined in advance.

As Luiggi Mendoza says;

In order to get the desired result, OP just have to change System.out.print to System.error.print or catch the Error and print it using e.printStacktrace(System.out). Or even better, use a logger that handles all this work for you

It is additionally worth noting that your catch statement does not catch this new Error() because Error!=Exception

like image 94
Richard Tingle Avatar answered Oct 17 '22 11:10

Richard Tingle


Change

    catch (Exception ex) 

into

    catch (Throwable ex) 

which catches more (Throwable being the base class). It also catches the stack trace in badMethod, which probably does e.printStacktrace(), which calls e.printStacktrace(System.err). Exception is for checked Exception, not RuntimeExceptions.

To the console both writers (PrintStreams), System.out and System.err are written simultaneous, in different threads: so really mixed up.

like image 28
Joop Eggen Avatar answered Oct 17 '22 10:10

Joop Eggen