In a Java try{} ... catch{} ... finally{} block, code within the finally{} is generally considered "guaranteed" to run regardless of what occurs in the try/catch. However, I know of at least two circumstances under which it will not execute:
If System.exit(0) is called; or,
if an Exception is thrown all the way up to the JVM and the default behavior occurs (i.e., printStackTrace() and exit)
Are there any other program behaviors that will prevent the code in a finally{} block from executing? Under what specific conditions will the code execute or not?
EDIT: As NullUserException pointed out, the second case is actually not true. I thought it was because the text in standard error printed after that in standard out, preventing the text from being seen without scrolling up. :) Apologies.
If you call System.exit() the program exits immediately without finally being called.
A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.
An infinite loop would also prevent a finally being called.
The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath to be thrown in the target thread. This can be caught (it's an Error) and the finally block will be called.
public static void main(String[] args) {
testOutOfMemoryError();
testThreadInterrupted();
testThreadStop();
testStackOverflow();
}
private static void testThreadStop() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.stop();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testThreadInterrupted() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.interrupt();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testOutOfMemoryError() {
try {
try {
List<byte[]> bytes = new ArrayList<byte[]>();
while(true)
bytes.add(new byte[8*1024*1024]);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow() {
try {
try {
testStackOverflow0();
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow0() {
testStackOverflow0();
}
prints
finally called after java.lang.OutOfMemoryError: Java heap space
finally called after java.lang.InterruptedException: sleep interrupted
finally called after java.lang.ThreadDeath
finally called after java.lang.StackOverflowError
Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!
Infinite loop in the try block.
Corrupt RAM? Program no longer runs as written? I've actually debugged that once on a DOS machine.
Testing the finally block in different statement in try block.
public static void main(String [] args){
try{
System.out.println("Before Statement");
/*** Statement ***/
System.out.println("After Statement");
}
catch(Exception e){
}
finally{
System.out.println("Finally is Executed");
}
Statements in which finally block is executed are following:
Thread.currentThread().interrupted();
Thread.currentThread().destroy();
Thread.currentThread().stop();
Thread.sleep(10);
Thread.currentThread().interrupt();
Runtime.getRuntime().addShutdownHook(Thread.currentThread());
If there is any exception occurred.
If there is no exception.
Statements in which finally block is not executed are following:
Thread.currentThread().suspend();
System.exit(0);
JVM crashed.
Power to CPU chip goes off.
OS kills JVM process.
Runtime.getRuntime().exit(0);
Runtime.getRuntime().halt(0);
There is a chance of partial execution when finally itself throws an exception (or leads to an error)
One could be "A finally is a part of daeomon thread it may not be executed".
The only times finally won't be called are:
if the power turns off
if you call System.exit()
if the JVM crashes first
if there is an infinite loop in the try block
if the power turns off
I think when JVM exits suddenly due to any reason, that can be a cause the control will not enter into the the finally block and never execute.
You can make it a part of Daemon Thread. You may use the method setDaemon(boolean status) which is used to mark the current thread as daemon thread or user thread and exit the JVM as and when required. This will enable you exit the JVM before finally{} is executed.
Another possible instance of a finally block never executing would be due to a design where the method returned before the try block was entered, as in the cases of some very bad code I've seen from time to time:
public ObjectOfSomeType getMeAnObjectOfSomeType() throws SomeHorrendousException {
if (checkSomeObjectState()) {
return new ObjectOfSomeType();
}
try {
// yada yada yada...
} catch (SomeHorrendousException shexc) {
// wow, do something about this horrendous exception...
} finally {
// do some really important cleanup and state invalidation stuff...
}
I know none of you would ever do this, so I hesitated to add this as a possible scenario, but thought, eh, it's Friday, what the heck ; )
Related
public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Exiting via InterruptedException");
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}}
result
Starting ADaemon
Exiting via InterruptedException
This should always run?
I tried to the code sample from "Thinking in Java" 4th edition, but it did't get the result as described in the book, the finally block is still being executed, why is that so? BTW I am using oracle jdk 10.0.1.
-------------update----------
It seems there is something run with my maven-runner plugin, I disabled it and it just get the same result as described in the book.
You say that the book says:
"the finally block may not be executed".
(Emphasis added.)
That is not the same as saying:
"the finally block will not be executed".
I think that the book is implying that it is unspecified (and possibly JVM specific) whether daemon thread gets an interrupt (or something) when the application exits.
Certainly, if the daemon thread caught and ignored the "interrupted" exception as follows, then I would expect that the finally to never be executed.
public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Caught InterruptedException");
}
}
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
}
I would expect similar behavior if the daemon thread was not executing interruptible code.
This should always run? Yes. Unless the JVM actually halts the finally block is guaranteed to be entered. Something like
System.exit(-1);
in the catch block will prevent that. If that is what you want. It will also stop the JVM! The book is warning you that if all other threads are completed, the daemon thread may never be scheduled before the JVM terminates. You are directly calling start(). Consider using
SwingUtilities.invokeLater(t);
It probably won't run unless you remove t.setDaemon(true);
The finally block is a powerful (and dangerous if used incorrectly) tool which will almost always run after the try or catch block completes (despite some small cases which are highlighted above).
Look at this example:
try{
throw new Exception();
}catch(Exception e){
return;
}finally{
System.out.println("Shouldn't run?");
}
If this was in a method, the finally block would still be executed (never do this as it is a bad practise). It is designed to perform any cleanup despite the result of the operation you did such as closing streams (which can now be done automatically through paranthesis in the statement 'try').
I've got 5 threads; main (represents bank) and 4 other custom threads (client) that I've created. Each of the custom threads has about 6 instructions in it's run method and these instructions execute a method on a shared resource/monitor. I'll post the relevant codes to keep it short and simple. What I want to do is display a message once all threads have finished executing. One of the threads is vulnerable to deadlock in my situation and to overcome it, i force the main thread to sleep a certain amount of time to give all the threads a chance to finish their execution and once the main thread has woken up, it checks if the other threads are alive.. if yes then throw an exception using the .interrupt() method. Now what I expected to happen was that the thread that catches the interruption to go in a terminated state but weirdly it doesn't and still maintains its running state. And what I've noticed is that it continues executing the statements in its run method but after the statement that made it go into the wait state.
In the main thread I check if clientB thread is alive, if yes, throw an exception.
if(clientB.isAlive()){
clientB .interrupt();
}
ClientB's run method is a simple basic run method that calls methods from a monitor.
#Override
public void run() {
System.out.println(threadName + " is in ThreadGroup: " + threadGroupName);
threadState = Student.currentThread().getState().name();
System.out.println("State of studentThread: " + threadState);
Random rnd = new Random();
try {
Code number 1
{...}
Code number 2
{...}
Code number 3
{...}
Code number 4
{...}
Code number 5
{...}
System.out.println("ClientB Terminating");
} catch (InterruptedException ex) {
ex.printStackTrace();
System.out.println("ClientB got interuppted.");
return;
}
}
As you can see, I haven't got any while loops or anything in ClientB's run method. And this is the monitor method that ClientB calls:
#Override
public synchronized void withdrawal(Transaction t) {
while (t.getAmount() > this.balance) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Withdrawal method interuppted.");
return;
}
}
{...}
notifyAll();
}
Now when I give main method 10 seconds for all the threads to complete their actions, all the other threads seem to finish within that time apart from ClientB on Code 2 of its method and after calling interrupted, I expect the thread to catch that exception and get killed but what I've noticed is that the Withdrawal method interrupted. is printed out on the console but not ClientB got interrupted. and it then goes to finish executing code 3,4,5 and then prints out ClientB Terminating and stops.. why is this?
When the exception is catched in withdrawal, it exits the method with a return, so the processing of the exception ends there.
UPDATE:
if you want to continue the processing of the InterruptedException outside of the withdrawal method, you can do this:
#Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
while (t.getAmount() > this.balance) {
wait();
}
{...}
notifyAll();
}
Yes, Maurice is right. You do not pass your exception to the calling method.
You should replace return with throw new InterruptedException(ex.getMessage());
Also if you do not use the try catch in the withdrawal method, it will also do what you intend it to do.
To catch the same exception in several places, it should be rethrown, for example:
#Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
while (t.getAmount() > this.balance) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Withdrawal method interuppted.");
throw ex;
}
}
{...}
notifyAll();
}
This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 6 years ago.
I'm aware of headaches that involve returning in try/catch/finally blocks - cases where the return in the finally is always the return for the method, even if a return in a try or catch block should be the one executed.
However, does the same apply to System.exit()? For example, if I have a try block:
try {
//Code
System.exit(0)
}
catch (Exception ex) {
//Log the exception
}
finally {
System.exit(1)
}
If there are no exceptions, which System.exit() will be called? If the exit was a return statement, then the line System.exit(1) would always (?) be called. However, I'm not sure if exit behaves differently than return.
The code is in an extreme case that is very difficult, if not impossible, to reproduce, so I can't write a unit test. I'm going to try to run an experiment later today, if I get a few free minutes, but I'm curious anyway, and perhaps someone on SO knows the answer and can provide it before or in case I can't run an experiment.
No. System.exit(0) doesn't return, and the finally block is not executed.
System.exit(int) can throw a SecurityException. If that happens, the finally block will be executed. And since the same principal is calling the same method from the same code base, another SecurityException is likely to be thrown from the second call.
Here's an example of the second case:
import java.security.Permission;
public class Main
{
public static void main(String... argv)
throws Exception
{
System.setSecurityManager(new SecurityManager() {
#Override
public void checkPermission(Permission perm)
{
/* Allow everything else. */
}
#Override
public void checkExit(int status)
{
/* Don't allow exit with any status code. */
throw new SecurityException();
}
});
System.err.println("I'm dying!");
try {
System.exit(0);
} finally {
System.err.println("I'm not dead yet!");
System.exit(1);
}
}
}
Simple tests including catch too reveal that if system.exit(0) does not throw a security exception, it will be the last executed statement (catch and finally are not executed at all).
If system.exit(0) does throw a security exception, catch and finally statements are executed. If both catch and finally contain system.exit() statements, only statements preceding these system.exit() statements are executed.
In both cases decribed above, if the try code belongs to a method called by another method, the called method does not return.
More details here (personal blog).
Other answers have covered how the catch and finally blocks don't run if System.exit exits the JVM without throwing a SecurityException, but they don't show what happens in a "try-with-resources" block to the resources: Are they closed?
According to the JLS, Section 14.20.3.2:
The effect of the translation is to put the resource specification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.
Furthermore, all resources will have been closed (or attempted to be closed) by the time the finally block is executed, in keeping with the intent of the finally keyword.
That is, resources will be closed before a catch or finally block runs. What if they are closed somehow even if catch and finally don't run?
Here's some code to demonstrate that the resources in a "try-with-resources" statement aren't closed either.
I use a simple subclass of BufferedReader that prints a statement before calling super.close.
class TestBufferedReader extends BufferedReader {
public TestBufferedReader(Reader r) {
super(r);
}
#Override
public void close() throws IOException {
System.out.println("close!");
super.close();
}
}
Then I set up the test case of calling System.exit in the try-with-resources statement.
public static void main(String[] args)
{
try (BufferedReader reader = new TestBufferedReader(new InputStreamReader(System.in)))
{
System.out.println("In try");
System.exit(0);
}
catch (Exception e)
{
System.out.println("Exception of type " + e.getClass().getName() + " caught: " + e.getMessage());
}
finally
{
System.out.println("finally!");
}
}
Output:
In try
Therefore, not only do catch and finally blocks not run, a "try-with-resources" statement won't get a chance to close its resources if System.exit succeeds.
finally block will be executed no matter what....even if try block throws any throwable(exception or error).....
only case finally block does not execute...is when we call System.exit() method..
try{
System.out.println("I am in try block");
System.exit(1);
} catch(Exception ex){
ex.printStackTrace();
} finally {
System.out.println("I am in finally block!!!");
}
It will not execute finally block. The program will be terminated
after System.exit() statement.
If you consider this behaviour problematic, and you need fine control over your System.exit calls, then the only thing you can do is wrap the System.exit functionality in your own logic. If we do that, we can get finally blocks executed and get resources closed as part of our exit flow.
What I'm considering doing is wrapping the System.exit call & functionality in my own static method. In my implementation of exit I would throw a custom subclass of Throwable or Error, and implement a custom Uncaught exception handler with Thread.setDefaultUncaughtExceptionHandler to handle that exception. Thus my code becomes:
//in initialization logic:
Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> {
if(exception instanceof SystemExitEvent){
System.exit(((SystemExitEvent)exception).exitCode);
}
})
// in "main flow" or "close button" or whatever
public void mainFlow(){
try {
businessLogic();
Utilities.exit(0);
}
finally {
cleanUpFileSystemOrDatabaseConnectionOrWhatever();
}
}
//...
class Utilities {
// I'm not a fan of documentaiton,
// but this method could use it.
public void exit(int exitCode){
throw new SystemExitEvent(exitCode);
}
}
class SystemExitEvent extends Throwable {
private final int exitCode;
public SystemExitEvent(int exitCode){
super("system is shutting down")
this.exitCode = exitCode;
}
}
This strategy has the added "benefit" of making this logic testable: to test that the method containing our "main flow" actually requests the system to exit, all we have to do is catch a throwable and assert that is the write type. For example, a test for our business logic wrapper might look like:
//kotlin, a really nice language particularly for testing on the JVM!
#Test fun `when calling business logic should business the business`(){
//setup
val underTest = makeComponentUnderTest(configureToReturnExitCode = 42);
//act
val thrown: SystemExitEvent = try {
underTest.mainFlow();
fail("System Exit event not thrown!")
}
catch(event: SystemExitEvent){
event;
}
//assert
assertThat(thrown.exitCode).isEqualTo(42)
The major downside to this strategy is that it is a way of getting functionality out of exception flow, which often has unintended consequences. The most obvious one, in this case, is that anywhere you've written try { ... } catch(Throwable ex){ /*doesnt rethrow*/ } will have to be updated. In the case of libraries that have custom execution contexts, they will need to be retrofitted to also understand this exception.
On balance, this seems like a good strategy to me. Does anybody else here think so?
In example below, if System.exit(0) is before the exception line, the program will be terminated normally, so the FINALLY will not execute.
If the System.exix(0) is the last line of the try block, here we have 2 scenarios
when exception is present then finally block is executed
when exception is not present then finally block is not executed
.
package com.exception;
public class UserDefind extends Exception {
private static int accno[] = {1001,1002,1003,1004,1005};
private static String name[] = {"raju","ramu","gopi","baby","bunny"};
private static double bal[] = {9000.00,5675.27,3000.00,1999.00,1600.00};
UserDefind(){}
UserDefind(String str){
super(str);
}
public static void main(String[] args) {
try {
//System.exit(0); -------------LINE 1---------------------------------
System.out.println("accno"+"\t"+"name"+"\t"+"balance");
for (int i = 0; i < 5; i++) {
System.out.println(accno[i]+"\t"+name[i]+"\t"+bal[i]);
//rise exception if balance < 2000
if (bal[i] < 200) {
UserDefind ue = new UserDefind("Balance amount Less");
throw ue;
}//end if
}//end for
//System.exit(0);-------------LINE 2---------------------------------
}//end try
catch (UserDefind ue)
{
System.out.println(ue);
}
finally{
System.out.println("Finnaly");
System.out.println("Finnaly");
System.out.println("Finnaly");
}
}//end of main
}//end of class
I am currently running a Thread from a Service to do some background work.
Now there is the possibility that the Thread crashes or I want to
interrupt the thread from the Service. So how am I supposed to:
stop the Thread realiable, (hard)
catch exceptions and call the Service about the crash
handle InterruptedException if interrupted while sleep()
is Thread.isInterrupted a good way to detect if the Thread stopped?
What I have done so far is the following:
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
So at first I am running my Thread until it gets interrupted.
If any exception occurs, I want to start a new Thread, therefore
my Service implements a listener interface and I call it, once an
Exception is thrown. I know that catching everything is discouraged,
but I need to know if the Thread stops, without polling Thread.isAlive()
all the time.
Additionally to my four questions above:
is my code reliable and does what I need?
is it ok to call interrupt on the Thread itself?
Thanks!
You are not actually interrupting your own thread because the catch block is outside of the while loop. Therefore, any exception would stop execution immediately.
Interruption is essentially just a request (usually from another thread) to stop doing what you are doing. The thread is free to ignore it and keep doing what it is doing. Normally you have to throw an exception in response to an interrupt, or stop execution some other way such as just breaking from the loop (you need this around the //what to do here? comment). It so happens that some library methods are "responsive to interruption" meaning they will throw an exception if the thread is ever interrupted, such as Thread.sleep(), which you will most likely have in your sleep call.
I recommend picking Java Concurrency In Practice. Among the excellent concurrency material, there is a chapter on interrupts which is very helpful.
EDIT:
I would remove the code where you interrupt your own thread. You will also need to rethrow the InterruptedException as a runtime exception to get out of the execution loop. Usually people will create a new Exception that extends RuntimeException that is something like MyInterruptedException. You can then add it to the catch block around your loop so that you know when the thread was interrupted vs execution failed.
As a general example you can do something like this:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
we have a nice and effective method called stop()(Thread.stop(void):void) which is deprecated, but it works and it's lovely.
Note that stop() throws ThreadDeath at the target thread which is not an exception(and it could any other throwable too), but an Error, so your code will not catch any signal about this.
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
Beside dear friend stop() we also have pause() method too, and it really pauses the target thread.
Not just one solution out there, but if it's really critical to keep thread run and run the emergency(or itself) just after any crash, you may run it as a separately app/process, plus get progress status(if any) that ensures you the target thread/app is not freezed(blocked,...)
I was wondering what's the difference between code inside finally block and code after finally block
A small test program shows the difference:
public class FinallyTest {
public static void main(String[] args) throws Exception {
try {
boolean flag = true;
if (flag) {
throw new Exception("hello");
}
} finally {
System.out.println("this will get printed");
}
System.out.println("this won't show up");
}
}
The program throws an exception, the JVM executing the program catches it and prints it out.
What gets written to the console is:
this will get printed
Exception in thread "main" java.lang.Exception: hello
at snippet.FinallyTest.main(FinallyTest.java:7)
Once the exception is thrown the only things that that thread will execute (until the exception is caught by the JVM) are finally blocks (where the exception is leaving a try-block that the finally belongs to).
Here I am adding more to the example provided above and may help someone in the future and hope will avoid some confusion.
Lets Start.
Actually, it depends on the flow control of the program. That means if the program is written in such a way that if your code is handling the exceptions thrown in the try blocks and if you are handling them in the catch block, then your code after finally block will get executed after the code inside the finally block.
Example 1: here the exceptions have been handled and hence the code after finally, block executes.
public class TestFinally {
public static void main(String[] args) throws Exception {
try {
boolean flag = true;
if (flag) {
throw new Exception("hello");
}
}
catch(Exception e){
System.out.println("catch will get printed");
}
finally {
System.out.println("this will get printed");
}
System.out.println("this won't show up");
}
}
result:
catch will get printed
this will get printed
this won't show up
Example 2: if the exceptions in the try block have not been handled properly as told by Nathan above, then the code after the finally block does not get executed.
public class TestFinally {
public static void main(String[] args) throws Exception {
try {
boolean flag = true;
if (flag) {
throw new Exception("hello");
}
}
// not handling the exception thrown above
/*catch(Exception e){
System.out.println("catch will get printed");
}*/
finally {
System.out.println("this will get printed");
}
System.out.println("this won't show up");
}
}
result:
this will get printed
Exception in thread "main" java.lang.Exception: hello
at com.test.TestFinally.main(TestFinally.java:36)
So conclusively, to sum up, the code inside the finally block gets executed always except in some cases where the thread has been stopped or killed before the finally block or in case if there are any exit programs written in a try block. Whereas the code after finally depends on the code written in try-catch-finally blocks and the exception handling.
If the catch block re-throws an exception (or throws a new one), the finally block is executed. Anything after the finally block will not be executed.
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated. - http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
If you throw the exception on the catch block, or if you return something on your try block, it will execute the finally block. If not on the finally block (after try/catch/finally) it wont work. Here is a simple example for you to understand: Try it without the finally block and you will see that the line where it prints the message "Closing resources..." will never be executed.
try {
return "Something";
} catch (Exception e) {
throw e;
} finally {
System.out.println("Closing resources (Connections, etc.)...");//This will always execute
}