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");
}
Related
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)
I want to reproduce a part of InterruptedException behavior but I don't understand how it works...
So I have this code:
public static void main(String [] args){
try{
}catch(InterruptedException ie){
}
}
When I try to compile it I get this compiler error
Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body
I made a custom Exception which is not really an Exception because it doesn't extend Exception...
class MyException extends Throwable{
}
public static void main(String [] args){
try{
}catch(MyException ie){
}
}
Which shows the same compiler error
Unreachable catch block for MyException. This exception is never thrown from the try statement body
Then I did this
public static void main(String [] args){
try{
throw new MyException();
} catch(MyException e){
e.printStackTrace();
}
try{
throw new InterruptedException();
} catch(InterruptedException e){
e.printStackTrace();
}
}
And both of them compile fine.
But now comes the tricky part..
public static void main(String [] args){
try{
throw new MyException();
} catch(Exception e){
e.printStackTrace();
} catch(MyException e){
e.printStackTrace();
}
try{
throw new InterruptedException();
} catch(Exception e){
e.printStackTrace();
} catch(InterruptedException e){
e.printStackTrace();
}
}
Compiler says
Unreachable catch block for InterruptedException. It is already handled by the catch block for Exception
Can you tell me how InterruptedException shows the "Unreachable catch block for InterruptedException. This exception is never thrown from the try statement body" compiler error and extends Exception in the same time, because when I extend exception my custom exceptions don't show this compiler error
As an example:
class MyException extends Exception{}
public static void main(String [] args){
try{
}catch(MyException me){
}
}
This code doesn't throw any compiler error
But the following code does
class MyException extends Throwable{}
public static void main(String [] args){
try{
}catch(MyException me){
}
}
This occurs because InterrupedException is a subclass of Exception, but Exception is already caught by the preceding catch block.
Section 11.2.3 of the JLS states:
It is a compile-time error if a catch clause can catch an exception class E1 and a preceding catch clause of the immediately enclosing try statement can catch E1 or a superclass of E1.
The block in the InterruptedException catch block would be unreachable code, which would be the justification for this compiler error.
You are chatching throwable exception so it has to be thrown from somewhere
by the way : my compiler shows error for 1st script and for 2nd script
class TestExceptions {
public static void main(String[] args) throws Exception {
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
throw new RuntimeException();
} finally {
System.out.println("finally");
}
}
}
Following are the outputs when I try to run the code in eclipse multiple times. I believed so far that whenever the last line of the code from either try/catch block is about to be executed (which could be return or throws new Exception() type of stmt), finally block will be executed, but here the output different every time? Can anyone clarify if my assumption is right or wrong?
try
catch
Exception in thread "main" finally
java.lang.RuntimeException
at TestExceptions.main(TestExceptions.java:9)
Exception in thread "main" try
catch
java.lang.RuntimeException
at TestExceptions.main(TestExceptions.java:9)
finally
This is clearly because eclipse is printing the error stream and output stream without proper synchronization in console. Lot of people have seen issues because of this.
Execute the program in a command prompt and you will see proper output every time.
while agreeing with #Codebender, you can replace all the thows exception and replace them with printStackTrace(); then the exceptions and out will be printed in syn.
EG:
public static void main(String[] args) throws Exception {
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
e.printStackTrace();
} finally {
System.out.println("finally");
}
}
}
I am having this code. In aMethod() try block is there, but no catch block to handle the thrown exception. And the output generated is finally exception finished. Can anyone explain me how's this happening?
public class Test
{
public static void aMethod() throws Exception
{
try /* Line 5 */
{
throw new Exception(); /* Line 7 */
}
finally /* Line 9 */
{
System.out.print("finally "); /* Line 11 */
}
}
public static void main(String args[])
{
try
{
aMethod();
}
catch (Exception e) /* Line 20 */
{
System.out.print("exception ");
}
System.out.print("finished"); /* Line 24 */
}
}
finally block is always executed, exception or not*. That's what is causing the first printout "finally" that you see.
Next, the uncaught exception propagates to main, where it gets caught in the catch block, producing "exception".
After that, your program prints "finished" to complete the output.
That is how finally works. Moreover, if you do this
try {
throw new Exception();
} catch (Exception e) {
...
} finally {
...
}
the code in both catch and finally blocks would be executed.
* There are corner cases when you can construct a program that exits without executing a finally block, but it has nothing to do with the code in your example.
You declared aMethod() as throws Exception, so it can throw any checked exception and doesn't have to catch anything.
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.