my question is simple. How to force JAVA to terminate the program I am writing when any Exception occures?
I am currenlty using Swing and when a NullPointer exception is thrown, the program keeps on running in the background :| While running this way I can only close it from the task manager. The bad thing is that when I run the same program again, a second instance is created and I don't know why, but when I have more than 1 instance of the same program, one time I get null exception, next time not, next time yes, next time not.... Complete randomness.
Thanks in advance!
This article will be of interest wrt. catching exceptions (which, ideally, you should be eliminating).
The idea is that you can plug in a proxy to wrap the invocation of the Swing event, and catch any resultant exceptions. You can then decide what to do - alert someone, exit etc.
Obviously it seems that your program has at least a bug that you can try to iron out with a debugger.
As for your question, an exception will terminate your program if it isn't caught. So if you always throw your exceptions, including in the main method, when one happen will cause the program to exit.
However, as Mac said in the comment
A Swing app has an event loop in the way. The event loop catches Throwable (I believe), so he can't exactly control what's caught in the normal way.
You should fix your bugs in your program. An exception will terminate the program if it isn't caught, you are probably catching the exception. You can always exit a program with System.exit(0);
Related
In my JavaFX 8 app, I have a thread that runs a loop and occasionally updates the UI. Somewhere in this thread, there's an exception causing me grief. Finding it wouldn't be a problem, except exceptions on worker threads don't seem to be logged to System output the same as those on the main program thread.
What I mean is, when I run the program, if something breaks in main(), IntelliJ prints the exception message and a stack trace to the Run view (standard out, AFAIC). On the other hand, if something breaks in my thread, I don't get the same verbose output. In fact, most of the time, I don't get anything at all - just a mysteriously non-functioning program.
Is there another step I need to take to capture errors in worker threads? Is my environment misconfigured? This makes debugging next to impossible - any help appreciated!
Between Samuel's comment and some searching, I've got my answer; Runnables tend to consume their errors, so they're never thrown up to the main thread. This means that with no error handling, they simply disappear and the thread is broken.
The solution in my case is to add try/catch blocks in my task. This is dumping errors the way I expect now.
(I guess your answer/comment means I should turn my comment into an answer.)
Depending on your threading model exceptions are not propagated to the main thread, they just kill the thread they are thrown from. You might benefit from adding a try/catch to your "run" method when starting the thread.
In a situation where a fatal exception occurs, it can be assumed that the program is no longer in a safe state to run and should be terminated as soon as possible. However, I would like to inform the user what fatal error has occurred without requiring them to go searching through log files. Is the best solution to terminate all other executing Threads, only leaving the current thread alive for calling up a JDialog?
This was my attempt at the solution:
public void killAlienThreads() {
Thread[] threads;
while ((threads = Thread.getAllStackTraces().keySet().toArray(new Thread[0])).length != 1) {
for (Thread thread : threads) {
if (thread != Thread.currentThread())
thread.stop();
}
}
}
After this method is called, the current thread goes on to alert the user of the issue, and then close off the program once the remaining dialog is disposed.
There are many issues with this code. For one, new threads could be created while attempting to shut down all of them, this requires a loop that only breaks when it knows only the current thread is left. Also, as Eclipse warns me, Thread.stop() is deprecated, however Thread.interrupt() is not guaranteed to immediately stop a thread. Regardless, instead of terminating all other threads, this method simply gives me a barrage of InterruptedExceptions.
So, how can a program in an "unsafe state" be safely terminated while still allowing for an error dialog to inform the user?
EDIT:
Let me explain a couple things to make my question more clear. When I say "fatal exception" I mean a checked Exception (not an Error) that my program has caught and does not know how to deal with. When one of these errors occurs it can be assumed that the program is no longer in a functional state (or it is "unsafe") and should be terminated as soon as possible. However, waiting for the user to click the "OK" button on an error dialog can take an indefinite amount of time. So, I wish to terminate the program immediately when a "fatal exception occurs" without having to wait for the user to acknowledge the error dialog and close it.
While throwing a proper exception generally leave a lot of objects in a valid state, calling an unsafe method like Thead.stop() can completely corrupt important state and cause even more bad side effects.
The safest way is to let the main process die as quickly as possible and use another daemon process to report the error.
If you have to do it from within the JVM, you'll probably have to look at debugging or instrumentation APIs as it is not possible to interrupt a thread that does not call interruptable methods.
If I want to check if some preconditions are present in order to run a java program what is best?
Do:
System.exit(1);
Or throw a RuntimeException in main to end the main thread? (No other threads running yet)
Ideally you terminate your threads gracefully. System.exit(1) works too, but it is better if your threads get signalled that they need to stop what they're doing and terminate by finishing what they're doing (i.e. executing their method till the end). It depends on your design obviously.
Throwing a RuntimeException seems too ungraceful and could lead you to behaviour you don't actually want.
You're better off calling exit as exceptions are used to help you catch errors in programming flow and deal with them accordingly.
From a user's perspective having the application print to System.err the issues and then closing gracefully is much more intuitive than seeing a stack trace or other code notations like EXCEPTION that they shouldn't be expected to understand.
If you want a stack trace, go with the RuntimeException, if not System.exit(1) is cleaner.
Either is good, but I would prefer to use the System.exit() as the RuntimeException could be considered misleading.
Not having more information than what you posted I would do something like this:
public static void main(String[] args) {
boolean precondition = ... // determine your precondition here
if (precondition) {
// run program
} else {
System.out.println("Preconditions not satisfied.");
}
}
Never force the exit. Program your runtime method in a way allowing your application to run out of methods and close by itself. I suggest drawing a graph before any structural application.
Does throwing an Exception have to cause the program to terminate?
I think its no, I just want to make sure
It depends on the thread where the exception is thrown, and on the other threads running on the same time in the application.
An uncaught exception terminates the thread where it was thrown. If the rest of the threads are only daemon threads, then yes, the application will be terminated.
According to Thread.setDaemon(boolean) documentation:
The Java Virtual Machine exits when the only threads running are all daemon threads.
No, it does not have to cause it to terminate. You could catch the exception and do something useful with it, like show a message to the user that an error occurred and why.
In Java and .NET, if you don't handle an exception, it will most like cause your program to terminate.
Simply throwing an exception will not terminate the program, as such. It is what happens after it was thrown that determines what will occur.
Failing to catch an exception will likely cause the program to terminate, but the act of throwing one will not. At the very least, any application should have some kind of last line of defense for catching all otherwise unhandled exceptions and handling them (even if handling them means, for some at least, throwing them outside of the application and terminating because something external to the application expects this).
Only "Unhandled Exceptions" will cause your program to crash. To handle exceptions you use the following form
try {
// May Throw ApocalypseException
functionThatMightBlowUpTheWorld();
}
catch (ApocalypseException e){
System.err.println("We accidentally almost blew up the world because: ");
System.err.println(e.message);
}
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 ....