Abnormal termination in catch block? [duplicate] - java

This question already has answers here:
Java - shutting down on Out of Memory Error
(9 answers)
Closed 6 years ago.
I'm working on a simple application and now I'm not quite sure how to deal with errors occured while executing application. I'm particularly worried about OutOfMemoryError. Example:
try{
while(true){
//do some job
}
} catch (Exception e){
System.out.println("Exception occured");
} catch (Throwable t){
//log entry of abnormal termination
System.exit(1);
} finally {
//Terminate application normally
}
Is it a correct way to deal with such situation? I mean to attempt to terminate application normally in finally block and just kill JVM in catch(Throwable t).
The issue is finally will never be executed if, say, OutOfMemoryError was thrown.

I don't think that's even needed, if you want to kill your JVM on OutOfMemoryException, you can include some JVM flags:
-XX:OnOutOfMemoryError="kill -9 %p"
It may be possible to free up some memory when hitting OutOfMemoryException depending on what you're doing and it's probably better to explicitly try and catch OutOfMemoryException rather than catching Throwable which includes everything that can be thrown.

If it is a single threaded application, you could just log the OOM, and let the VM finish normally, don't invoke the System.exit(). If it is multi-threaded application, you need to have a policy of shutting it down. In every scenario it is up to you which resources and how should be handled when you need to shutdown your application. You are worried about finally not invoking after System.exit(), if you have more threads they will be killed and you have no control when, they also wouldn't have chance for any finaliztion. If you would like to shutdown your app gracefully then you need to program it in such way to have the logic that does this.

If you call System.exit(...) in a catch block for some exception then a finally block will not be executed if the exception is caught.
Assuming that is what you want to happen ... then you have coded your exception handling correctly.
Is that the "correct" way to deal with this? Well, if this is what you want to happen (i.e. if you want any Error exceptions to cause the normal termination logic to be skipped) then it is correct. But ultimately, you need to decide for yourself.
Having said that, if you are concerned that your application won't be able to perform the termination because it is out of memory, then you could do something like this:
try {
int[] reserved = new int[1,000,000];
while(true){
//do some job
}
} catch (Exception e){
System.out.println("Exception occured");
} catch (Throwable t){
//log entry of abnormal termination
}
// Terminate application normally << HERE
If the JVM throws OOME, when you reach the "HERE" point, there will be a 8MB of reclaimable garbage in the heap. If the termination code fills the heap (again) then the GC will reclaim that garbage and there should be enough space to complete the termination.

Related

Why is a try catch statement required? [duplicate]

This question already has answers here:
Why do I need to handle an exception for Thread.sleep()?
(3 answers)
Closed 4 years ago.
Why is a try/catch exception handling statement required in Java for the below line:
TimeUnit.MILLISECONDS.sleep(250);
I just want my code to sleep for 250 milliseconds before executing the next line. Why is a try-catch statement required? I can’t forsee any exceptions with this. The sleep function in python doesn't require a try catch.
The exception I get in the IDE without adding the try catch is:
Error:(124, 40) error: unreported exception InterruptedException; must be caught or declared to be thrown
When I surround it in the try catch as per below it works fine:
try {
TimeUnit.MILLISECONDS.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
You need to catch the exception simply because the thread running (sleeping) might be interrupted and you need to catch the interruption.
From the Oracle description of the InterruptedException
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.
Interrupting a thread that is sleeping is a very important part of Java. It provides control when you need to stop an application (or a process) and do not want to be halted from doing so due a thread sleeping. The InterruptException allows developers to catch interrupt attempts and deal with it.
Maybe your beef is with checked exceptions in general.... which is a feature of Java that many people do not like. We can understand your frustration with checked exceptions. You can read up more on checked exceptions in Java via Google.

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

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)

Java - Will try-with-resources call .close() if the user closes the program unexpectedly? [duplicate]

This question already has answers here:
How does Java's System.exit() work with try/catch/finally blocks? [duplicate]
(6 answers)
Closed 6 years ago.
I'm working on some server code for a program I'm developing and I'm using try-with-resource statements to close the sockets.
try (
ServerSocket serverSocket = new ServerSocket(port);
Socket clientSocket = serverSocket.accept();
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
) {
out.println("This is the server! Hooray! :D");
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
The problem is, what if the user decides to close the program before the try block finishes? Will the .close() methods be called?
This is on oracle's website:it will be closed regardless of whether the try statement completes normally or abruptly But I'm not sure if that includes if the user just closes the program before the try finishes or just if the program crashes.
Thanks.
Yes/no,
"The try-with-resources statement ensures that each resource is closed at the end of the statement"
This can be found at Oracle
Just think about it as a finally block. The finally will always be executed.
"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."
This can be found at Oracle
No it will not.
Runtime.addShutdownHook gives more guarantees if you need them but still not 100% because it will not be called if JVM crashes/someone terminate JVM forcibly from outside.
Best possible solution here it to have wrapper process that starts your Java application, watches over it and does what you need when watched process terminates.
If I understand your question correctly,I think it Wont close. The try block has to gracefully complete or catch some exception in order to close the resource. so it should be a checked exception. I believe if you catch a RuntimeException in your try with resources then the resource will be closed. But it wont close the resource with the thread or JVM crashes for issues like OOM.

Java Exception handling mechanism

In Java,If I didn't catch the thrown Exception then the Thread execution stops there else if I catch the same then the Thread execution continues after the catch block.Why Java Exception handling designed in this way.
Thx
The purpose of an exception is to let the program understand that Something Weird Has Happened, and so doing what would ordinarily be next in the program is very likely to be wrong. A function you called couldn't give you a real answer, and you were relying on that answer, so it had to stop you.
There are two ways this can end: you handle the exception (via a catch block), or the entire program stops.
If your program doesn't know what to do when these things happen, it's best to do nothing. Let the Exception crash the thread, and then you can check the crash log later, and find out exactly what crashed the program and why. If your program can't handle an error, the Exception's "crash the thread" behavior lets you see what error was unhandled, so you can change the program to make it able to handle this kind of situation in the future, or prevent the situation from occuring.
Some errors might be pretty normal, though, and shouldn't stop the entire program- you need to have a way to recover from them. That's what a catch block is for: a chance to say "Hello Java, I know just what to do about this problem", and then do it. A Catch block lets you clean up the program and move on, if you can. Java assumes your Catch block deals with the problem and makes it go away. If there's a new problem, or for that matter the same one, you need to throw the caught exception again, or maybe a new one, so something else can try to fix the problem- even if that something else is you, as a programmer.
If exceptions always crashed the program, there would be no way to handle errors that are expected and can be dealt with. But if absolutely nothing is ready to handle the error, the program can't keep running, because now something's gone weird and it doesn't know what to do because you didn't program it to do anything.
In Java,If I didn't catch the thrown Exception then the Thread execution stops there else if I catch the same then the Thread execution continues after the catch block.
There is a third case. If the thread has an Thread.UncaughtExceptionHandler (registered by calling thread.setUncaughtExceptionHandler(handler)), then it will be notified in the event of an uncaught exception on the thread stack ... before the thread exits. (In fact, the behaviour is a bit more complicated than this; see the javadocs.)
Why Java Exception handling designed in this way.
Because the alternative is far worse ... in most cases.
Assuming that the thread has caused the run() method to terminate ('cos you didn't catch the exception), then the only thing you could do "not stop" would be have the thread infrastructure call run() again.
But the uncaught exception typically means something BAD has happened. Typical run() methods are not designed so them multiple times will do something sensible. And if the run() method just failed for some unknown reason (as far as the run() method is concerned), it is even less likely that calling it again will work.
Besides, in the few cases where it is sensible for your run() method to catch and resume from every exception, you can always code it to do that. And if you don't want to the thread to resume, you can implement an "uncaught exception handler" to do notify something else and (maybe) start higher level recovery.
The only thing that is maybe slightly questionable about the current design is that Thread termination due to an uncaught exception is often silent. But the cure for that is to implement a default uncaught exception handler that makes some noise ....

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