try with resource, will resource clean if thrown exception is not caught? - java

What happens when a try-with-resource throws an exception which is caught outside? Will a cleanup still be performed?
Sample:
public void myClass() throws customException {
try (Connection conn = myUtil.obtainConnection()) {
doSomeStuff(conn);
if (someCheck)
throw new customException(somePara);
doSomeMoreStuff(conn);
conn.commit();
} catch (SQLException e) {
log.error(e);
}
}
The part I'm concerned with is when the customException is thrown. I do not catch this exception with the catch of my try-with-resource. Hence I wonder if the connection cleanup will be performed in this scenario.
Or do I need to catch and rethrow the connection, like this:
public void myClass() throws customException {
try (Connection conn = myUtil.obtainConnection()) {
doSomeStuff(conn);
if (someCheck)
throw new customException(somePara);
doSomeMoreStuff(conn);
conn.commit();
} catch (SQLException e) {
log.error(e);
} catch (customException e) {
throw new customException(e);
}
}

A documentation has an answer to your exact question
Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the writeToFileZipFileContents method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.
Please have a look https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Yes, the cleanup will happen... if the close() method correctly handles the cleanup:
Example of execution
public class Main {
public static void main(String[] args) throws Exception {
try (AutoCloseable c = () -> System.out.println("close() called")) {
throw new Exception("Usual failure");
}
}
}
(shortened by Holger in the comments)
Output on stdout:
close() called
Output on stderr:
Exception in thread "main" java.lang.Exception: Usual failure
at Main.main(Main.java:4)
Example of execution with an exception thrown in the close() method
(suggested by Holger in the comments)
public class Main {
public static void main(String[] args) throws Exception {
try (AutoCloseable c = () -> { throw new Exception("Failure in the close method"); }) {
throw new Exception("Usual failure");
}
}
}
No output on stdout.
Output on stderr:
Exception in thread "main" java.lang.Exception: Usual failure
at Main.main(Main.java:4)
Suppressed: java.lang.Exception: Failure in the close method
at Main.lambda$main$0(Main.java:3)
at Main.main(Main.java:3)

Related

In a finally block, can I tell what exception has been thrown?

In a finally block, can I tell what exception has been thrown?
I understand, that we can verify in a finally block if an exception had been thrown.
I can't envision a situation in which this would ever a sensible thing to do, but you can try something like this:
class Main {
public static void throwsException() throws Exception {
throw new Exception();
}
public static void main(String[] args) {
Exception caughtException = null;
try {
throwsException();
}
catch (Exception e) {
caughtException = e;
e.printStackTrace();
}
finally {
System.out.println(caughtException);
}
}
}
catch block and finally are 2 different scopes . The exception caught in the catch block is not visible to finally block. You can use the Alexander answer to print the exception in the finally block.

Exception in try with resources clause

class Demo
{
public static void main(String args[]) throws java.io.IOException
{
try(FileInputStream fin = new FileInputStream("Demo.txt"))
{
//This block is executed successfully
}
System.out.println("Will it be executed if error occurs in try clause");
}
}
Suppose that the code in try block is executed successfully as mentioned in the code, and some exception occurs in try with resource clause, that means exception occurs in auto closing of file.
How that exception in the try with resource clause will be handled?
What I want to ask is that will that exception be thrown to JVM and will terminate my program abruptly and the println statement will not be executed?
Can I catch that exception so that remaining program can also be executed?
If an exception is thrown by the close method of an AutoClosable it will indeed be thrown after the try block has been executed.
If you need to handle the exception you can simply add a catch clause to your try clause.
The following code illustrates the behavior:
public class Foo {
public static class Bar implements AutoCloseable {
#Override
public void close() {
throw new RuntimeException();
}
}
public static void main(String args[]) {
try (Bar b = new Bar()) {
// This block is executed successfully
}
System.out.println("Will it be executed if error occurs in try clause");
}
}
It terminates the JVM with the stack trace:
Exception in thread "main" java.lang.RuntimeException
at test3.Foo$Bar.close(Foo.java:14)
at test3.Foo.main(Foo.java:25)
25 is the line where the closing } for my try clause is.
It could be handled by using:
try (Bar b = new Bar()) {
// This block is executed successfully
} catch (Exception e) {
// ...
}
only add catch clause, to catch the exception otherwise program will be terminated
public static void main(String[] args) throws FileNotFoundException, IOException {
try(FileInputStream fin = new FileInputStream("Demo.txt"))
{
//This block is executed successfully
}
catch(Exception e)
{
e.printStackTrace();
}
System.out.println("Will it be executed if error occurs in try clause");
}
I think with a finally the rest of the program will be run, please try it and report.
class Demo
{
public static void main(String args[]) throws java.io.IOException
{
try(FileInputStream fin = new FileInputStream("Demo.txt"))
{
//This block is executed successfully
} finally {
System.out.println("Will it be executed if error occurs in try clause");
}
}
}
Just delete the file Demo.txt and run the following code.
The simplest way to throw such exception is to run this code, with no existing resource (Demo.txt in this case):
public static void main(String args[])
{
try(FileInputStream fin = new FileInputStream("Demo.txt"))
{
} catch(IOException exc) {
System.out.println("An exception has occured. Possibly, the file does not exist. " + exc);
}
System.out.println("Will it be executed if error occurs in try clause");
}

Why it is okay in java 7 to catch an IOException even if IOException will never be thrown

public class SampleCloseable implements AutoCloseable {
private String name;
public SampleCloseable(String name){
this.name = name;
}
#Override
public void close() throws Exception {
System.out.println("closing: " + this.name);
}
}
and the main class
public class Main{
public static void main(String args[]) {
try(SampleCloseable sampleCloseable = new SampleCloseable("test1")){
System.out.println("im in a try block");
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}
}
But when i removed the throws exception on close() method inside SampleCloseable
i am getting a compiler error saying that IOException is never thrown in the corresponding try block.
Because you're throwing a generic Exception. Since an IOException inherits from Exception, it might be thrown by the close() method. The caller doesn't know that it doesn't actually get thrown. It only sees the method signature that says that it could.
In fact, the close() method is free to throw any Exception of any kind. Of course that's bad practice, you should specify what specific Exceptions you're throwing.
Your confusion may that around the fact the in Java 7, the exception that is [declared to be] thrown from the close method is thrown inside the try block, so your catch block has to catch it as well.
Your close method is declared to throw an Exception, so your catch blocks have to catch that, or the method has to be declared to throw Exception.
And since IOException is a subclass of Exception, you are of course allowed to try and catch that as well, as long as your also catch/declare Exception itself.
See JLS 14.20.3.2:
The meaning of an extended try-with-resources statement [...] is given
by the following translation to a basic try-with-resources statement
(ยง14.20.3.1) nested inside a try-catch or try-finally or
try-catch-finally statement.
Your code is effectively translated to the below. Although a bit longish, it should be clear from the below what's happening in your code.
public static void main(String args[]) {
try {
Throwable primaryEx = null ;
SampleCloseable sampleCloseable = new SampleCloseable("test1")
try {
System.out.println("im in a try block");
} catch (Throwable t) {
primaryEx = t;
throw t;
} finally {
if (sampleCloseable != null) {
if (primaryEx != null) {
try {
sampleCloseable.close();
} catch (Throwable suppressedExc) {
primaryEx.addSuppressed(suppressedExc);
}
} else {
sampleCloseable.close();
}
}
} catch (IOException e) {
System.out.println("IOException is never thrown");
} catch (Exception e) {
} finally{
System.out.println("finally");
}
}

Throw an exception inside the method body and catch it after

The main class:
class IO
{
static void m() throws Exception
{
try
{
throw new Exception();
} finally{
System.out.println("finally");
}
}
public static void main(String [] args)
{
try {
m();
} catch (Exception ex) {
System.out.println("catch");
}
System.out.println("finish");
}
}
Output:
finally
catch
finish
That behavior is unclear for me. Clause 11.3 of JLS 8 says:
If no catch clause that can handle an exception can be found, then the
current thread (the thread that encountered the exception) is
terminated. Before termination, all finally clauses are executed and
the uncaught exception is handled according to the following rules:
If the current thread has an uncaught exception handler set, then that
handler is executed.
Otherwise, the method uncaughtException is invoked for the ThreadGroup that is the parent > of the current thread. If the ThreadGroup and its parent ThreadGroups do not override
uncaughtException, then the default handler's uncaughtException method is invoked.
I expected that the output will be finally only because current thread is terminated. I haven't produced any other threads, since the output must be finally, but it is not true. Help me to understand, please.
If no catch clause that can handle an exception can be found, [...]
But you do have a catch clause that can handle the exception. Your m method will complete abruptly as a result of the exception being thrown. The exception will be caught and handled inside your main method which will then complete normally along with the main thread.
It might be easier to look at it like this, by replacing the function with the code from it.
class IO
{
public static void main(String [] args)
{
try { //4 Now goes to the outer try
try //2 Checks this try for the catch, but doesn't find it
{
throw new Exception(); //1 Hits the exception
} finally{ //3 Executes this because there is no catch for this try
System.out.println("finally");
}
} catch (Exception ex) { //5 Finds the catch
System.out.println("catch");
}
//6 Continues as if nothing happened
System.out.println("finish");
}
}
The following is the flow:
class IO
{
static void m() throws Exception
{
try
{ //2
throw new Exception();
} finally{
//3
System.out.println("finally");
}
}
public static void main(String [] args)
{
try {
m();//1 method called
} catch (Exception ex) {
//4 the control returns
System.out.println("catch");
}
//5
System.out.println("finish");
}
}
The thread is only terminated if the exception is not handled.

Exception thrown in catch and finally clause

On a question for Java at the university, there was this snippet of code:
class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}
public class C1 {
public static void main(String[] args) throws Exception {
try {
System.out.print(1);
q();
}
catch (Exception i) {
throw new MyExc2();
}
finally {
System.out.print(2);
throw new MyExc1();
}
}
static void q() throws Exception {
try {
throw new MyExc1();
}
catch (Exception y) {
}
finally {
System.out.print(3);
throw new Exception();
}
}
}
I was asked to give its output. I answered 13Exception in thread main MyExc2, but the correct answer is 132Exception in thread main MyExc1. Why is it that? I just can't understand where does MyExc2 go.
Based on reading your answer and seeing how you likely came up with it, I believe you think an "exception-in-progress" has "precedence". Keep in mind:
When an new exception is thrown in a catch block or finally block that will propagate out of that block, then the current exception will be aborted (and forgotten) as the new exception is propagated outward. The new exception starts unwinding up the stack just like any other exception, aborting out of the current block (the catch or finally block) and subject to any applicable catch or finally blocks along the way.
Note that applicable catch or finally blocks includes:
When a new exception is thrown in a catch block, the new exception is still subject to that catch's finally block, if any.
Now retrace the execution remembering that, whenever you hit throw, you should abort tracing the current exception and start tracing the new exception.
Exceptions in the finally block supersede exceptions in the catch block.
Java Language Specification
If the catch block completes abruptly for reason R, then the finally
block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
This is what Wikipedia says about finally clause:
More common is a related clause
(finally, or ensure) that is executed
whether an exception occurred or not,
typically to release resources
acquired within the body of the
exception-handling block.
Let's dissect your program.
try {
System.out.print(1);
q();
}
So, 1 will be output into the screen, then q() is called. In q(), an exception is thrown. The exception is then caught by Exception y but it does nothing. A finally clause is then executed (it has to), so, 3 will be printed to screen. Because (in method q() there's an exception thrown in the finally clause, also q() method passes the exception to the parent stack (by the throws Exception in the method declaration) new Exception() will be thrown and caught by catch ( Exception i ), MyExc2 exception will be thrown (for now add it to the exception stack), but a finally in the main block will be executed first.
So in,
catch ( Exception i ) {
throw( new MyExc2() );
}
finally {
System.out.print(2);
throw( new MyExc1() );
}
A finally clause is called...(remember, we've just caught Exception i and thrown MyExc2) in essence, 2 is printed on screen...and after the 2 is printed on screen, a MyExc1 exception is thrown. MyExc1 is handled by the public static void main(...) method.
Output:
"132Exception in thread main MyExc1"
Lecturer is correct! :-)
In essence, if you have a finally in a try/catch clause, a finally will be executed (after catching the exception before throwing the caught exception out)
Finally clause is executed even when exception is thrown from anywhere in try/catch block.
Because it's the last to be executed in the main and it throws an exception, that's the exception that the callers see.
Hence the importance of making sure that the finally clause does not throw anything, because it can swallow exceptions from the try block.
A method can't throw two exceptions at the same time. It will always throw the last thrown exception, which in this case it will be always the one from the finally block.
When the first exception from method q() is thrown, it will catch'ed and then swallowed by the finally block thrown exception.
q() -> thrown new Exception -> main catch Exception -> throw new Exception -> finally throw a new exception (and the one from the catch is "lost")
class MyExc1 extends Exception {}
class MyExc2 extends Exception {}
class MyExc3 extends MyExc2 {}
public class C1 {
public static void main(String[] args) throws Exception {
try {
System.out.print("TryA L1\n");
q();
System.out.print("TryB L1\n");
}
catch (Exception i) {
System.out.print("Catch L1\n");
}
finally {
System.out.print("Finally L1\n");
throw new MyExc1();
}
}
static void q() throws Exception {
try {
System.out.print("TryA L2\n");
q2();
System.out.print("TryB L2\n");
}
catch (Exception y) {
System.out.print("Catch L2\n");
throw new MyExc2();
}
finally {
System.out.print("Finally L2\n");
throw new Exception();
}
}
static void q2() throws Exception {
throw new MyExc1();
}
}
Order:
TryA L1
TryA L2
Catch L2
Finally L2
Catch L1
Finally L1
Exception in thread "main" MyExc1 at C1.main(C1.java:30)
https://www.compilejava.net/
The logic is clear till finish printing out 13. Then the exception thrown in q() is caught by catch (Exception i) in main() and a new MyEx2() is ready to be thrown. However, before throwing the exception, the finally block have to be executed first. Then the output becomes 132 and finally asks to thrown another exception new MyEx1().
As a method cannot throw more than one Exception, it will always throw the latest Exception. In other words, if both catch and finally blocks try to throw Exception, then the Exception in catch is swallowed and only the exception in finally will be thrown.
Thus, in this program, Exception MyEx2 is swallowed and MyEx1 is thrown. This Exception is thrown out of main() and no longer caught, thus JVM stops and the final output is 132Exception in thread main MyExc1.
In essence, if you have a finally in a try/catch clause, a finally will be executed AFTER catching the exception, but BEFORE throwing any caught exception, and ONLY the lastest exception would be thrown in the end.
The easiest way to think of this is imagine that there is a variable global to the entire application that is holding the current exception.
Exception currentException = null;
As each exception is thrown, "currentException" is set to that exception. When the application ends, if currentException is != null, then the runtime reports the error.
Also, the finally blocks always run before the method exits. You could then requite the code snippet to:
public class C1 {
public static void main(String [] argv) throws Exception {
try {
System.out.print(1);
q();
}
catch ( Exception i ) {
// <-- currentException = Exception, as thrown by q()'s finally block
throw( new MyExc2() ); // <-- currentException = MyExc2
}
finally {
// <-- currentException = MyExc2, thrown from main()'s catch block
System.out.print(2);
throw( new MyExc1() ); // <-- currentException = MyExc1
}
} // <-- At application exit, currentException = MyExc1, from main()'s finally block. Java now dumps that to the console.
static void q() throws Exception {
try {
throw( new MyExc1() ); // <-- currentException = MyExc1
}
catch( Exception y ) {
// <-- currentException = null, because the exception is caught and not rethrown
}
finally {
System.out.print(3);
throw( new Exception() ); // <-- currentException = Exception
}
}
}
The order in which the application executes is:
main()
{
try
q()
{
try
catch
finally
}
catch
finally
}
It is well known that the finally block is executed after the the try and catch and is always executed....
But as you saw it's a little bit tricky sometimes check out those code snippet below and you will that
the return and throw statements don't always do what they should do in the order that we expect theme to.
Cheers.
/////////////Return dont always return///////
try{
return "In Try";
}
finally{
return "In Finally";
}
////////////////////////////////////////////
////////////////////////////////////////////
while(true) {
try {
return "In try";
}
finally{
break;
}
}
return "Out of try";
///////////////////////////////////////////
///////////////////////////////////////////////////
while (true) {
try {
return "In try";
}
finally {
continue;
}
}
//////////////////////////////////////////////////
/////////////////Throw dont always throw/////////
try {
throw new RuntimeException();
}
finally {
return "Ouuuups no throw!";
}
//////////////////////////////////////////////////
I think you just have to walk the finally blocks:
Print "1".
finally in q print "3".
finally in main print "2".
I think this solve the problem :
boolean allOk = false;
try{
q();
allOk = true;
} finally {
try {
is.close();
} catch (Exception e) {
if(allOk) {
throw new SomeException(e);
}
}
}
To handle this kind of situation i.e. handling the exception raised by finally block. You can surround the finally block by try block: Look at the below example in python:
try:
fh = open("testfile", "w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print "Going to close the file"
fh.close()
except IOError:
print "Error: can\'t find file or read data"

Categories