Here is the skeletal for the code:
flag1=True
flag2=True
do {
try {
if (){
throw new IllegalArgumentException();
}
.
.
.
do {
if () {
}
else {
}
.
.
.
if () {
}
} while (flag2);
flag1 = false;
} catch (RuntimeException ex) {
flag1 = true;
} catch (Exception ex) {
flag1 = true;
} catch (Error ex) {
flag1= true;
}
}
} while (flag1);
}
I am using junit4 for testing. I need to cover all the try catch blocks for testing as well.
I wrote a test case satisfying the first if condition and hence throwing illegal argument exception, but after throwing the exception the code moves to the do loop with flag1 always staying true.
To start off it sounds like you might be a Java beginner. If that's the case, let me suggest reading up on exception handling in Java. I think that will make it easy for you to understand the cause of this behavior. Here are some quick tutorials on that topic from Oracle: https://docs.oracle.com/javase/tutorial/essential/exceptions/
With that said, here is my explanation of what is causing the behavior you described: 1. flag1 remains true. 2. looping doesn't stop.
1.
The reason why flag1 is not set to true is that when IllegalArgumentException is thrown, all code between the place it is thrown and the exception catch blocks will be skipped. This includes skipping the line flag1 = false;.
2.
The reason the while loops do not exit when IllegalArgumentException is thrown is that IllegalArgumentException inherits from RuntimeException as you can see here: https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalArgumentException.html . This means that your catch block catch (RuntimeException ex) will catch the thrown exception. Thus, what will happen is that the code in the RuntimeException catch block (retry = true;) will be executed and then the execution will continue from after the try-catch block. Since this is still inside the outer do-while loop, looping will continue.
Related
Does anyone know why SonarQube detects a violation of the rule "Conditionally executed blocks should be reachable" (squid:S2583) in the following example? Is this a false positive?
In this piece of Java code, a file is read and an EOFException (or multiple of them) can occur in the process of reading the input stream. Thus, the exception is caught and handled, and a flag is set to remember that it happened. However, Sonar does not consider the line exHappened = true; in the first catch block and claims that variable is always false:
public static boolean doSomething() {
boolean exHappened = false;
try (DataInputStream s = new DataInputStream(new FileInputStream("test"))) {
LOGGER.info("Doing something...");
}
catch (EOFException eof) { // this Exception can definitely happen
exHappened = true;
}
catch (IOException io) {
LOGGER.error("sorry", io);
}
if (exHappened) { // Sonar thinks this condition is always false
return false;
}
else {
return true;
}
}
To make it even more clear, add a throw new EOFException() into the try { }, then the condition will always be true and Sonar still claims that it always false...
(I'm using SonarQube 5.6.6 and SonarJava plugin 4.13.0.11627)
This seems to be a problem in how catch blocks are handled during data flow analysis in SonarJava. Catch block catching subtype of the exception declared in the throws declaration of called method is not being considered, hence the assignment to the variable is never seen by the engine.
I created following ticket to fix this problem https://jira.sonarsource.com/browse/SONARJAVA-2483
In the code below I was wondering if an exception was thrown in the for loop and the error message was added to the JSON object in the catch block, will the program return to the next iteration of the for loop after the exception was thrown? Or will it break the for loop and return the object?
JSONOBject obj = new JSONObject();
try
{
for(i=0; i<10; i++)
{
//do things in here that may throw an exception
obj.put("message","did not throw exception");
}
{
catch(Exception e)
{
obj.put("message",e.getMessage());
}
return obj;
An exception will terminate the method, because after the catch block the next statement is return.
If you want to continue the loop, put the entire try/catch inside the loop, as in:
for (.... whatever ...)
{
try
{
something
}
catch(Exception e)
{
obj.put("message",e.getMessage());
}
}
In this case the loop will execute all specified iterations, and each exception caught will add a new message to obj.
No - the loop will be exited from the point when the exception is thrown - after catch block is done with.
In a try block as soon as an error is thrown execution in that block stops and control jumps over to the catch block. Therefore in your case the rest of the for loop is not executed.
You can move the try catch into the for loop if you wish to continue through the for loop.
This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 9 years ago.
This is what I'm trying to do:
try {
//code
} catch (Exception e) {
return false;
} finally {
//close resources
}
Will this work? Is it bad practice? Would it be better doing this:
boolean inserted = true;
try {
//code
} catch (Exception e) {
inserted = false;
} finally {
//close resources
}
return inserted;
Yes, it will. The only things that can prevent a finally block to execute (AFAIR) are System.exit(), and an infinite loop (and a JVM crash, of course).
The finally block is executed always, unconditionally, as the last thing the try-catch-finally block does. Even if you execute Thread#stop against it, the finally block will still execute, just as if a regular exception ocurred.
Not just that, if you return from finally, that return value will trample over the return from either try or catch.
BTW Your first example is not just fine, but preferred. In the second example the reader must chase around the assignments to the variable, which is a tedious job and lets bugs slip through very easily.
Both are approximately the same. However, be careful with the following case:
int i = 0;
try
{
//code
}
catch(Exception e)
{
return i;
}
finally
{
i = 1;
}
0 is what will be returned.
I just wanted to add that it's described in the specs:
If the catch block completes abruptly for reason R, then the finally block is executed.
where of course
It can be seen, then, that a return statement always completes abruptly.
I was responding to a slough of basic Java practice test questions and the correct answer to the following question slipped past me while taking the test.
Question: "If an exception is not caught, the finally block will run and the rest of the method is skipped - TRUE or FALSE?"
I am attempting to prove out the answer with the ThrowTest class (pasted at bottom) but I find Java exception handling to be somewhat unfamiliar. I compile the class as is with the ArrayIndexOutOfBoundsException portion of the catch block commented out. I then execute the class without passing an input parm thus creating an exception (the ArrayIndexOutOfBoundsException exception) . I would expect the final System.out.println would not execute and indeed it does not.
I find if I un-comment the ArrayIndexOutOfBoundsException catch block and recompile, the class then catches that specific error at run time and executes the "Rest of method" println at bottom. So, does my code prove the rest of "the rest of the method is skipped" or do I have to test it from a method other than the main method? Maybe there is a more straightforward method of testing it.
public class ThrowTest
{
public static void main(String[] args)
{
try
{
String anyString = args[0];
System.out.println("Try code executes");
}
catch(SecurityException e) //any old exception
{
System.err.println ("Error: SecurityException. ");
e.printStackTrace();
}
/* begin comment
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Error: Caught ArrayIndexOutOfBoundsException. ");
e.printStackTrace();
}
end comment */
finally
{
System.out.println("finally block executes!");
}
System.out.println("Rest of method executes!");
}
}
Regardless of what exception is thrown a finally block will always execute (barring any strange situations like out of memory), so given the following
try {
// do some code
}
catch (SomeException e) {
// exception handling
}
finally {
doFinallyStuff();
}
doOtherStuff();
doFinallyStuff will always execute here. But doOtherStuff will only execute under the following conditions:
No exceptions are thrown
SomeException is thrown and the catch block does not rethrow the exception up the chain
If another exception is thrown in the try block that is not handled by the catch block, doFinallyStuff will still execute, but doOtherStuff will not
Your code is indeed proving that everything works as you described. When you catch an exception, then the rest of the method thereafter executes. If you let the method throw the exception, its execution halts immediately. Either way, the finally block will always execute.
If you have:
catch (FooException ex) {
throw new BarException (ex);
}
catch (BarException ex) {
System.out.println("hi");
}
...and the first catch clause is triggered (i.e. FooExcepetion has occurred),
does the new BarException get immediately caught by the subsequent "catch" clause?
Or is the new BarException thrown one level up the continuation stack?
I realize this is a basic question. : )
It does not get caught by the 2nd catch clause, no.
Each catch clause in the list is tried, to see if it matches. The first one that matches is the only one that runs, then the code moves on to the finally clause.
Another result of this is that if you have:
try {
throw SubTypeOfException(...);
} catch(Exception e) {
... block 1 ...
} catch(SubTypeOfException e) {
... block 2 ...
}
then block 1 is the only one that will run, even though block 2 would have matched. Only the first matching catch clause is evaluated.
It's thrown one level up.
You'll need another try//catch block.