Flow Control with exception - java

When I run the following code, there are two result.
package scjp;
public class ExceptionTest {
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest();
test.method1();
}
public void method1() {
try {
System.out.println("Try Block");
if (!true) {
return;
} else {
throw new RuntimeException();
}
}finally {
System.out.println("Finally Block");
}
}
}
One result is
Try Block
Exception in thread "main" java.lang.RuntimeException
at scjp.ExceptionTest.method1(ExceptionTest.java:17)
at scjp.ExceptionTest.main(ExceptionTest.java:7)
Finally Block
and the other,
Try Block
Finally Block
Exception in thread "main" java.lang.RuntimeException
at scjp.ExceptionTest.method1(ExceptionTest.java:17)
at scjp.ExceptionTest.main(ExceptionTest.java:7)
Each time I am running the above code, the answer is changing. In my understanding, it should always be same result. Can you help me something???

The system error output stream (the stack trace above, likely in red in your console) is different than the system output stream (your System.out.println() statements). Hence error messages can be out of sync with normal console output since both streams write to the console, but independently of each other. The differences are as follows:
System.out.println("Some text");
prints to the out stream
System.err.println("Error occurred!");
prints to the error stream
The two can get intermixed when outputting to the same console.

The exception stacktrace is not printed on the same outputstrean (it is printed on System.err) and System.err and System.out are not synchronized.
To always have the same output you could print your messages on System.err rather than on System.out.

Related

Why a stacktrace of an exception is printed at last?

Here is my simple test code:
class Scratch {
public static void main(String[] args) {
try {
System.out.println("Line 1");
throw new RuntimeException();
} catch (RuntimeException e) {
e.printStackTrace();
} finally {
System.out.println("Line 2");
}
}
}
After running I'll get this:
Line 1
Line 2
java.lang.RuntimeException
at Scratch.main(scratch_4.java:5)
Process finished with exit code 0
I thought that "finally" code must be executed at last, but it's not.
What is the reason?
By default, printStackTrace prints to System.err, whereas you're writing to System.out. So you're writing to two different streams, and in your particular case it looks like the buffering involved has switched the output order from the actual execution order.
If you either write to a single stream (e.g. using System.err.println or calling e.printStackTrace(System.out)) or change your catch block to just write to System.out like your other lines do, you'll see the order of try => catch => finally.

Using the try catch statement to print out statements

#Test
public void test() throws Exception
{
try
{
//some code over here
}
catch(Exception e)
{
if(e.toString() == null)
{
System.out.print("Test Case: Successful");
}
else
{
System.out.println("Test Case: Failed");
System.out.println("Failing Reason: "+ e.toString());
}
}
}
Currently I have the above code.
However, when executing the JUnit.
Nothing was printed into the console.
Did I do anything wrong? Or is it that i cannot use System.out.println in JUnit.
So I have a second question:
Is it possible to print out the total amount of time taken to complete the JUnit test?
This code doesn't make sense.
If no exception is thrown, no exception is thrown, so you won't end up in the catch block; so there isn't a way you'd end up there in the "successful" case (unless you're testing explicitly for throwing an exception whose getMessage() returns null, which is... hmm; and in that case you should have a fail() as the last line of the try)
JUnit already handles failures for you. If your approach were the "right" way to do it, you'd have to put this code in every test case. What a lot of repeated code.
If the code in the try block fails by throwing an Exception, you catch and swallow the problem. Sure, it gets printed to the console, but JUnit has no means of capturing that, so it looks like the test passes. (It will still fail properly if an Error or other Throwable is thrown).
In short: just get rid of your try/catch block, leaving the code in the try, and let the testing framework do exactly what it is designed for.
Code in the catch block will only run if the code in the try block throws an exception. As you have it coded, it is not going to print anything out unless an exception is throw. This is likely what you meant:
#Test
public void test() throws Exception
{
try
{
//some code over here
// last line of try block
System.out.print("Test Case: Successful");
}
catch(Exception e)
{
System.out.println("Test Case: Failed");
System.out.println("Failing Reason: "+ e.toString());
}
}

Java - exception handling and force full exit from the system

Please excuse me for this kind of questions here but I am sure to get good explanation with sample which will make to have better understanding about java.
when the System.exit(0); gets executed, the system will break the execution flow and come out the system. this is what is my understanding as of now but I have came across some thing like the below :
Example 1 :
class FinallySystemExit
{
public static void main(String args[])
{
try
{
int a=2/0;
System.exit(0);
}
catch(Exception e)
{
System.out.println("i am in catch block");
}
finally
{
System.out.println("finally");
}
}
}
my understanding about the above code is it will not print anything and exit from the system but the output is :
i am in catch block
finally
Example 2
class FinallySystemExit
{
public static void main(String args[])
{
try
{
int a=2/1;
System.exit(0);
}
catch(Exception e)
{
System.out.println("i am in catch block");
}
finally
{
System.out.println("finally");
}
}
}
when i execute the above code it prints nothing
The difference between two programs are :
First Program :
int a=2/0;
and the
Second Program :
int a=2/1;
I am totally confused and my basic understanding is broken here.
Could some one explain the reason please.
Thanks
In Example 1 :
You perform int a=2/0;
This will throw java.lang.ArithmeticException as you are dividing a number by zero.
As your code is surrounded by try - catch the exception is caught and it printed the statement in catch block and went to finally block
In Example 2:
You perform int a=2/1;
So there is no problem at all.
After executing the above line, your program executed System.exit(0);. So No chance of executing the finally block. That is the reason you don't get any output in this case.
In the first snippet, there is Divide-by-zero error and so the System.exit() is not even called. In the second snippet System.exit() is called and so the JVM exited

Confused with try-catch-finally issue? [duplicate]

This question already has answers here:
Confusing output from infinite recursion within try-catch
(7 answers)
Closed 9 years ago.
I tried to figure out execution order of try-catch-finally in java. I thought execution order should be
try
catch (if error occurred/ exception caught)
finally (whether exception caught or not)
But I am confused with the result of the following
public class TryCatchFinally {
static int i = 0;
public static void main(String[] args) {
try {
System.out.println(i++);
main(args);
} catch (StackOverflowError e) {
System.out.println("Catch");
} finally {
System.out.println("Finally");
}
}
}
Out put(part of an out put)
9127
9128
9129
9130
CatcFCatch // what is the wrong here???
Finally
Finally // there are more Finally printed here.
My question is what is really happening here?
Let me add more why it is not printing "Catch"???
I am getting this out put when run this in IntelliJ IDEA. But when I run in terminal I am getting out put as follows.
9151
9152
9153
9154CatchFinallyCatch
Finally
Finally
Finally
Finally
Chances are that you get a stackoverflow error somewhere inside the println call (possibly because some flushing is going on or something similar), leaving the println method in a inconsistent state (having printed part of what it was supposed to).
That can easily happen when you're already handling a StackOverflowError, because at that point you're already dangerously close to an overflowing stack (since you just recovered from one at a point very close to the problem).
My interpretation looks something like this:
main calls itself recursively a lot ...
you call main for the 9130th time recursively
it prints that number
it calls itself for the 9131st time
it tries to print that number, but throws a StackOverflowError, since the stack is full
you enter the catch and try to print "Catch"
during that println call another StackOverflowError happens
the finally block is executed, because the catch block completed (abruptly)
it tries to print "Finally"
during that println call yet another StackOverflowError happens
that StackOverflowError is caught in the 9130th invocation of main
it prints "Catch" (sucessfully, because the stack is now 1 element shorter!)
the finally-block is executed and prints Finally successfully, because the stack is now 1 element shorter.
more finally blocks execute.
That is because of recursive calls to main. So as you are calling main in main, you are entering multiple times the try catch block, and you are returning from it the same amount of times as you ented it after first StackOverflow occurence. This is the reason on multiple finnalies.
EDIT:
As I saw some downvotes, without any reasonable explanation, if someone thinks I'm wrong, just print the damn i counter with decrementaion in finally block.
public static void main(String[] args) {
try {
System.out.println(i++);
main(args);
} catch (StackOverflowError e) {
System.out.println("Catch");
} finally {
System.out.println("Finally: "+ (i--));
}
}
Are you using an IDE (eclipse or similar), if yes then it could be due to that.
Here is the result of my attempt -
// Code
public static void main(String[] args) throws IOException {
File file = new File("resources/ouput.txt");
file.createNewFile();
PrintStream printStream = new PrintStream(file);
System.setOut(printStream);
overflowTester(0);
}
private static void overflowTester(int index) {
try {
System.out.println(index++);
overflowTester(index);
} catch (StackOverflowError e) {
System.out.println("Catch");
} finally {
System.out.println("Finally");
}
}
// Output
0
1
2
3
4
5
6
7
8
9
10
...
...
...
9666
Catch
Finally
...
...
Finally
Note: '9666' was printed on the 9667th line and the last Finally was on the 19336th line.
In my case, running the following program :
private static int index = 0;
public static void main(String[] args) throws IOException {
try {
System.out.println(index++);
main(args);
} catch (StackOverflowError e) {
System.out.println("Catch");
} finally {
System.out.println("Finally");
}
}
from the command-prompt, yielded similar result :
0
1
2
3
4
5
...
...
9667
Catch
Finally
...
...
Finally
with '9667' being printed on the 9668th line and the last 'Finally' being printed on the 19338th line.

Behavior of nested finally in Exceptions

Today at work, I had to review a code snippet that looks similar to this mock example.
package test;
import java.io.IOException;
import org.apache.log4j.Logger;
public class ExceptionTester {
public static Logger logger = Logger.getLogger(ExceptionTester.class);
public void test() throws IOException {
new IOException();
}
public static void main(String[] args) {
ExceptionTester comparator = new ExceptionTester();
try {
try {
comparator.test();
} finally {
System.out.println("Finally 1");
}
} catch(IOException ex) {
logger.error("Exception happened" ex);
// also close opened resources
}
System.out.println("Exiting out of the program");
}
}
It's printing the following output.I expected an compile error since the inner try did not have a catch block.
Finally 1
Exiting out of the program
I do not understand why IOException is caught by the outer catch block. I would appreciate if anyone can explain this, especially by citing stack unwinding process
A finally block represents a task that has to be done under both normal and abnormal conditions.
Example: You take an interview candidate to lunch. While at lunch, you find out he's wanted by the police for murder. Exception! Lunch is over, the interview is a total loss, but... you still have to pay for lunch.
try {
meetForLunch(interviewCandidate);
}
finally {
lunchBill.pay();
}
Note that paying for lunch hasn't taken care of the exception, you've still got to do something about the murderer at your interview. It's just a loose end that has to be taken care of before processing with damage control.
Most finally blocks are used in that way: A file needs to be closed whether you successfully saved the data or not, a database connection needs to be closed whether the transaction was approved or not, etc.
And the exception continues outward on its merry way, looking for a matching catch block in an enclosing scope.
Note that finally blocks will always run unless the process ends while the try block is still executing.
I think the problem is that your function
public void test() throws IOException {
new IOException();
}
Doesn't actually throw an exception - it just creates a new IOException() object. Changing this to
public void test() throws IOException {
throw new IOException();
}
should fix this.
The code above does not require much of an explanation - not definitely involving call stacks!. What is your confusion?did I miss something?
Here is my explanation
First point
You don't need both a catch and a
finally block. You can have one of
them or both of them with a
try-block, but not none of them.
The code inside the finally clause
will always be executed, even if an
exception is thrown from within the
try or catch block. If your code has
a return statement inside the try or
catch block, the code inside the
finally-block will get executed
before returning from the method.
So in the above code, an exception was never thrown (because you are not using throw in the test() method)
However, finally block got executed as promised by the the language spec and you got the output Finally 1. The next statement in the sequence of execution is the System.out.println("Exiting out of the program"); as the catch block never reached as there are no IOExceptions. So, Exiting out of the program is printed.

Categories

Resources