Valid Commands That Keep A Finally-block From Executing in Java [duplicate] - java

This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 7 years ago.
So I've been assigned to teach a block on exception handling, and I've run into a question I don't have an answer for. What valid (e.g., don't result in either a compiler, or a run-time, error) commands in Java will keep a finally-block from executing?
A return statement won't do it, but a System.exit(0) statement will. My understanding is that a finally-block would execute no matter what. What (valid) statements will prevent a finally-block from doing so, and why?

Quoting Docs:
If the JVM exits while the try or catch code is being executed,
then the finally block may not execute. Likewise, if the thread
executing the try or catch code is interrupted or killed, the finally
block may not execute even though the application as a whole
continues.
Regarding your example about System.exit(), quoting Docs again
Terminates the currently running Java Virtual Machine. The argument
serves as a status code; by convention, a nonzero status code
indicates abnormal termination.
which means that finally will not be executed.
Simple example:
try {
System.out.println("try");
System.exit(0);
} finally {
System.out.println("finally");
}
The above example will print only try but not finally

To quote Oracle's tutorials:
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
System.exit will just quite the JVM, thus preventing the finally block from running, as will killing the thread containing that block from another thread. Another edge case is having an infinite loop in the try block, which will simply prevent it from ending, so the finally loop will never be reached.

I see three cases to never reach finally block (or any further instructions in the stack frame):
Sudden thread death (including JVM exit)
stack frame operations
Infinite loop ; whatever it's active (while (true)) or passive (acquiring lock, waiting for notification, etc.)
Only native code (including own JVM mechanisms) is supposed to kill thread or play with stack frames. Fatal system errors are also an option.
However, JVM implementations are free to offer such (undesirable ?) feature across his specific API (ie sun.misc.Unsafe) or via an ugly implementation of Java SE API (ie Thread.destroy)

Related

Ignoring an InterruptedException properly [duplicate]

This question already has answers here:
Why invoke Thread.currentThread.interrupt() in a catch InterruptException block?
(5 answers)
When does Java's Thread.sleep throw InterruptedException?
(8 answers)
Closed 1 year ago.
I am aware that ignoring an InterruptedException is actually a bad practice. But let's assume in my case it is necessary: it is a utils method in a deep place, which is called by different threads. Please also assume it is not possible to rethrow.
If my only option is to tell the system "ok, I will not sleep any further, but I cannot kill this thread myself. I will finish my job and hope that my caller takes care of your interruption request", is this the correct way of doing it?
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// ignore
Thread.currentThread().interrupt();
}
Does the method interrupt() do anything else other than resetting the interrupted flag?
Please also assume it is not possible to rethrow.
Impossible; you can always rethrow. throw new RuntimeException("unhandled", e); is never a compile time error - that should be your default choice for "I have no idea what this exceptions means or I cant be bothered to handle it". It's perfectly fine: It ensures that the code will be rolled up properly, you want that to happen when exceptions you can't handle / weren't expecting (heh) occur.
However, in this case, uniquely, 'I did not expect it' also means it cannot possibly happen.
InterruptedException
Note that InterruptedException cannot ever happen unless some code is explicitly doing it. You do not get interrupted when the system is running low on resources and needs you to clean up. You do not get interrupted because some code in java core or any third party library decided to interrupt you for funsies. You do not get interrupted when the user hits CTRL+C, or goes into the task manager and clicks 'end process'.
There is only one way to be interrupted, and it is when some java code running in your JVM process runs: yourThread.interrupt();.
Presumably, there are only two options:
[A] You never do this. The point is moot. Rethrow that thing using throw new RuntimeException(e); - you're writing code that is literally going to never ever run, stop worrying about it.
[B] You invoked interrupt(), explicitly. I assume it wasn't because the cat strolled on the keyboard :) - You had some intent by doing it. So, what is the intent? Whatever you intended to happen, program it in the catch block. The usual options are either to abort a thread entirely (so, just return;), or if you have a loop that sleeps, checks something, sleeps again, etc - to recheck (a poor man's wait/notify setup, in other words), or to re-read some configuration or otherwise re-perform some initialization procedure. It's up to you. There is no described style or rule.
Does the method interrupt() do anything else other than resetting the interrupted flag?
Yes, it returns true or false depending on whether it was up or not. But this is completely pointless. Everything in java that can throw InterruptedException +lowers that flag first_. There is therefore absolutely no point whatsoever in lowering the flag in the catch block - it has already been lowered if you ever get there. You EITHER get the flag raised on you, OR you get an InterruptedException (the flag is there because not everything throws InterruptedEx). Note that if your thread is sleeping due to some sleeping op that is not declared to throws InterruptedException, then it may interrupt or not - it depends on the OS capabilities. For example, if you're waiting for network traffic (e.g. calling read() on an InputStream derived from a java.net.Socket or whatnot), then interrupted the thread may either do nothing at all other than raise the flag, or, it will actually end up shutting down the threadsleep. In that case, the code in that InputStream will lower the flag and ends up throwing some sort of IOException (because it can't throw InterruptedException; InterruptedException is checked, and read() doesn't declare it).
Note that if the flag is raised, and you invoke any method that is specced to throw InterruptedException, said method will act IMMEDIATELY, it never goes to sleep in the first place. It lowers the flag and throws InterruptedException, instantly.
Therefore you rarely need to check the flag - very few threads lack a looping construct and very few threads will chug on for a long time without ever invoking anything that will end up invoking Thread.sleep() or obj.wait() somewhere along the line.
NB: The intent of the interrupted() method is to use it as the sole condition in a busy loop that doesn't otherwise call any code that would throw InterruptedException. e.g.:
while (!Thread.interrupted()) {
doSomethingThatNeverSleeps();
}
that'd be the whole body of your run() method. That will keep running forever and make your CPU fans make the laptop take off, at least until some other code tells the thread to call it a day by invoking .interupt(). As I said, rare that you need this construct, but that's what it is for.

Thread.stop() and finally [duplicate]

This question already has answers here:
Are Thread.stop and friends ever safe in Java?
(8 answers)
Closed 7 years ago.
I created a following Class named as ThreadClass (which is a thread as you can see),its structure is something like the following
class SomeTask implements Runnable
{
boolean someCondition=true;
public void run() {
try
{
while(someCondition)
{
//Here goes the Process Code
}
}
catch(Exception errorException)
{
//Catching the Exception
}
finally
{
////I expect that this finally should run every time ,whatever happens in the world
}
}
}
My question is about the finally block and the stop() method
As above class is implementing Runnable, so I can create the object of this class and start a thread of it by calling start() method.I am also aware of the fact that I can stop this thread by using stop() (Yes , I know it is deprecated) method .
What I want to clarify myself is that, if somehow I need to call the stop method on the ThreadClass's object, then can I rely on the finally block to execute even if the thread is stopped by calling stop() as I am doing some important closing things in the finally block.
Thread#stop works by throwing a ThreadDeath exception, it doesn't obliterate the thread instantaneously the way System.exit blows away the JVM. ThreadDeath can even be caught, although that's not a good idea. So try blocks are still relevant.
However, complicating this is that if the thread has stop called on it multiple times then, if the second stop is called when the thread is in a finally block then it could be thrown from the finally block so that the finally block would not complete then. And if the thread's cleanup takes a while then it might be likely that stop could be called more than once on it.
Or even if you only call stop once, if at the time that stop is called the thread happens to be already executing its finally block, then the stop would interfere with completing the finally block.
This is similar to what the technotes on Thread primitive deprecation point out:
1) A thread can throw a ThreadDeath exception almost anywhere. All synchronized methods and blocks would have to be studied in great detail, with this in mind.
2) A thread can throw a second ThreadDeath exception while cleaning up from the first (in the catch or finally clause). Cleanup would have to repeated till it succeeded. The code to ensure this would be quite complex.
So there are some cases that are problematic, it would be very difficult to make sure cleanup gets done properly. James' comment is correct, if at all possible you should use interruption for this kind of thing so that the thread can reliably finish its business.

Code not reaching "finally" block

The given java code is not going to the finally block, I thought these blocks were supposed to execute no matter what:
public static void main(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.out.println("Goodbye world");
}
}
System.exit(0);
will unload the JVM i.e no further java instructions are processed
That is the reason for not being exicuting the finally{}
As stated in the Java 6 System.exit() docs:
The call System.exit(n) is effectively equivalent to the call: Runtime.getRuntime().exit(n)
And, if you go and look at Runtime.exit() (my bold):
Terminates the currently running Java virtual machine by initiating its shutdown sequence. This method never returns normally.
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish. In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.
Basically, the only one this function can return (and hence allow the finally clause to run) is for it to raise a SecurityException because whatever security manager is running disallows exiting with the given code.
Yes, that's normal. The finally blocks is always executed, except in the case where the JVM is stopped before reaching the end of the code, which is your case here, as you exit the JVM.
The System.exit method stops the execution of the current thread and all others threads.
The presence of a finally does not give a thread special permission to continue executing.
A previous discusses this in great detail.
How does Java's System.exit() work with try/catch/finally blocks?
By System.exit(0) You are exiting from Jvm so no lines after this will get executed and That's why you are finding your finally block as unexecuted.

Java try finally variations

This question nags me for a while but I did not found complete answer to it yet (e.g. this one is for C# Initializing disposable resources outside or inside try/finally).
Consider two following Java code fragments:
Closeable in = new FileInputStream("data.txt");
try {
doSomething(in);
} finally {
in.close();
}
and second variation
Closeable in = null;
try {
in = new FileInputStream("data.txt");
doSomething(in);
} finally {
if (null != in) in.close();
}
The part that worries me is that the thread might be somewhat interrupted between the moment resource is acquired (e.g. file is opened) but resulting value is not assigned to respective local variable. Is there any other scenarios the thread might be interrupted in the point above other than:
InterruptedException (e.g. via Thread#interrupt()) or OutOfMemoryError exception is thrown
JVM exits (e.g. via kill, System.exit())
Hardware fail (or bug in JVM for complete list :)
I have read that second approach is somewhat more "idiomatic" but IMO in the scenario above there's no difference and in all other scenarios they are equal.
So the question:
What are the differences between the two? Which should I prefer if I do concerned about freeing resources (especially in heavily multi-threading applications)? Why?
I would appreciate if anyone points me to parts of Java/JVM specs that support the answers.
I don't think there is any reason to be concerned:
1) InterruptedException (e.g. via Thread#interrupt())
Calling Thread.interrupt() does not cause InterruptedException to be thrown spontaneously. The exception is only thrown within specific (and well documented) blocking methods; i.e. blocking I/O and synchronization methods. This exception cannot be thrown after returning from the stream constructor and before entering the try block.
or OutOfMemoryError exception is thrown
If an OutOfMemoryError is thrown, you cannot guarantee full recovery of the underlying file descriptor, no matter where you put the stream constructor. You should never attempt to recover from an OOM, so the question of whether the stream is closed is moot. Besides, this exception is only thrown on a thread that is actually attempting to allocate memory, and that is not happening at this point.
2) JVM exits (e.g. via kill, System.exit())
If the application is being forcibly terminated by an external kill or a System.exit() call, it does not matter if streams are closed properly. Besides, in both cases there is no guarantee that finally clauses will be executed.
3) Hardware fail (or bug in JVM for complete list :)
All bets are off. You have no way of knowing if anything will execute, let alone the finally blocks.
There is one more situation where a thread might receive an spontaneous exception at that point, with some (naive) expectation that it might recover. That is when some misguided programmer decides to call the deprecated Thread.stop() method. You might think that putting the stream constructor call inside the try block would help. But actually it won't, because the ThreadDeath exception could be raised inside the stream constructor between opening the underlying file and completing construction of the stream object. So the FD could leak anyway.
This is just one reason why Thread.stop() is deprecated. Don't use it.
a) Note that interrupting the thread with interrupt() will not take effect immediately, and may not have any effect at all, if the thread being interrupted does not cooperate. There is no way the thread will exit due to interrupt() during the execution of :
Closeable in = new FileInputStream("data.txt");
The only thing that will happen is that its interrupted flag of the thread will be turned on.
b) regarding OutOfMemoryError - I don't see how it can occur right after the construction of the input stream. It may occur in another thread, but this will have no immediate effect on this thread. The problem with OutOfMemoryError, is that your finally block may also fail, because there is not enough memory to complete it...
c) The only way I know that a thread can be interrupted aggressively is using the deprecated methods Thread.stop() and Thread.stop(Throwable).
See a similar discussion here:
Is this a safe way to release resources in Java?
My view is that is when you are working with a managed runtime, such as Java or .NET you really should not (and it's good!) concern yourself with things like your particular question. Only because you are completely disconnected from the underlying operating system and its native APIs. All you have to know is that you call Closable.close() in your finally block and your resource will always be freed.

Is there possibility that a finally block might not execute? [duplicate]

This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 2 years ago.
We know that no matter whether an exception is thrown, or caught and handled it, the finally block will get executed, So I was curious that is there any possibility that finally block will not executed.
And if System.exit() is called either in try or catch, then also will the finally gets called?
If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
Source: java.sun.com: Java Tutorial: The finally Block
System.exit() will prevent a finally block from executing.
In the Java documentation:
http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html
It explains Finally very well.
They do note that if the JVM exits, that the finally block will not be called. Or if a thread that is running the block of code gets killed, the finally block will not be called. In all other cases it will.
One thing I can think of right now is an OutOfMemoryError in which case there is a chance that no further code in your app can be executed.
try {
System.out.println("BEFORE");
System.exit(0);
System.out.println("AFTER");
} finally {
System.out.println("FINALLY");
}
this will give you the output:
BEFORE
System.exit(1); you can use
If some Java Native Interface method segfaults (a library function outside of java but called from there crashes) a finally method will also not be called because the entire JVM stops.
Errors in the JVM itself also result in a crash and prevent everything from continued execution.
the finally clause in the try-catch exception block always executes, irrespective of the occurrence of exception in the normal java program flow. If the execution flow is stopped before the finally clause then the finally block will not be executed.
we can use System.exit(1); before finally block and stop the execution flow of the program.
Another situation that I can think of (that is left out from the other answers) is when an exception is thrown inside a finally block, in that case the finally block will not be "completely" executed.

Categories