I've read through several examples of how to use an UncaughtExceptionHandler to pass exceptions from a nested thread to a parent thread. Currently, my nested thread's UncaughtExceptionHandler catches exceptions as it should. I've set it to pass exceptions to the parent thread's default UncaughtExceptionHandler.uncaughtException(...) method.
public void load() {
// Create the nested thread
final Thread loadingThread = new Thread(new Runnable() {
#Override
public void run() {
// Do stuff... throw an exception at some point
throw new RuntimeException("Something has gone horribly wrong!");
}
}
});
// Set up a custom exception handler for the nested thread
class LoadingThreadExceptionHandler implements UncaughtExceptionHandler {
// The parent exception handler
private UncaughtExceptionHandler defaultHandler;
// Constructor to get a handle on the parent's exception handler
public void LoadingThreadExceptionHandler() {
// Check if the parent thread has an exception handler
if (Thread.getDefaultUncaughtExceptionHandler() == null) {
System.out.println("The default handler is null");
}
// Get the parent's default exception handler
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
return;
}
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.prinln("This is the nested thread's handler");
// Pass it onto the parent's default exception handler
defaultHandler.uncaughtException(t, e);
}
};
// Set the custom exception handler on the loadingThread
loadingThread.setUncaughtExceptionHandler(new LoadingThreadExceptionHandler());
// Start the thread
loadingThread.start();
return;
}
Running this produces the following output:
This is the nested thread's handler
For whatever reason, the nested UncaughtExceptionHandler is called, but it doesn't seem to pass the exception to the parent thread's default UncaughtExceptionHandler, as nothing happens after that point. I did at one point suspect maybe the parent's default UncaughtExceptionHandler was null so, I added some logic in the constructor to check for this and print a message, but this doesn't seem to ever be the case. I've also attempted overriding the parent's default exception handler as well, although to no avail.
Am I missing something here? I cannot, for the life of me, understand why the parent's uncaughtException(...) method never seems to be called.
public void LoadingThreadExceptionHandler()
This is not being called, because it's not the constructor. When you invoked new LoadingThreadExceptionHandler(), the no-arg default constructor (which is created by the compiler if no constructor exists) is invoked.
To fix it, it should be without a return type:
public LoadingThreadExceptionHandler()
Related
Suppose I have 5 threads belonging to a thread group named "Fruits-group".
How can I assign UncaughtExceptionHandler to all threads of Fruits-group at one go?
I know we can define a global UncaughtExceptionHandler for all threads.
What I am looking for is assigning a UncaughtExceptionHandler to an entire thread-group?
TL;DR Subclass the ThreadGroup and override the uncaughtException() method.
A ThreadGroup is an UncaughtExceptionHandler, implementing the uncaughtException(Thread t, Throwable e) method:
Called by the Java Virtual Machine when a thread in this thread group stops because of an uncaught exception, and the thread does not have a specific Thread.UncaughtExceptionHandler installed.
The uncaughtException method of ThreadGroup does the following:
If this thread group has a parent thread group, the uncaughtException method of that parent is called with the same two arguments.
Otherwise, this method checks to see if there is a default uncaught exception handler installed, and if so, its uncaughtException method is called with the same two arguments.
Otherwise, this method determines if the Throwable argument is an instance of ThreadDeath. If so, nothing special is done. Otherwise, a message containing the thread's name, as returned from the thread's getName method, and a stack backtrace, using the Throwable's printStackTrace method, is printed to the standard error stream.
Applications can override this method in subclasses of ThreadGroup to provide alternative handling of uncaught exceptions.
UPDATE
If you want to be able to set an UncaughtExceptionHandler for the ThreadGroup, you can create a delegating subclass:
public class ExceptionHandlingThreadGroup extends ThreadGroup {
private UncaughtExceptionHandler uncaughtExceptionHandler;
public ExceptionHandlingThreadGroup(String name) {
super(name);
}
public ExceptionHandlingThreadGroup(ThreadGroup parent, String name) {
super(parent, name);
}
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return this.uncaughtExceptionHandler;
}
public void setUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) {
this.uncaughtExceptionHandler = uncaughtExceptionHandler;
}
#Override
public void uncaughtException(Thread t, Throwable e) {
if (this.uncaughtExceptionHandler != null)
this.uncaughtExceptionHandler.uncaughtException(t, e);
else
super.uncaughtException(t, e);
}
}
In general, though, it would likely be better to just implement the exception handling logic directly in the subclass, but this way, you can use an existing UncaughtExceptionHandler implementation.
I am trying to catch all unhandled exceptions that occur in a service
that runs in a separate process. In the onCreate for the service, I call
a method that calls Thread.setDefaultUncaughtExceptionHandler with
MyCustomExceptionHandler class. My examination of the logs indicates
that it is set but does not consistently get called for uncaught
exceptions. For example, when I hard code a divide by zero into the
service, it does not get called at all. Another example is a
NullPointerException that I forced which resulted in a call to my
handler but the stack trace did not point to the actual lines of code
that caused the exception.
public class ActivityEngineService extends android.app.Service {
/** Called when the service is first created. */
#Override
public void onCreate() {
super.onCreate();
setUncaughtExceptionHandler();
// Get the service that has a hard coded divide by zero running
}
public void setUncaughtExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler());
System.out.println("Thread.getDefaultUncaughtExceptionHandler(): " + Thread.getDefaultUncaughtExceptionHandler());
}
public class CustomExceptionHandler implements UncaughtExceptionHandler {
private UncaughtExceptionHandler defaultUEH;
public CustomExceptionHandler() {
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
public void uncaughtException(Thread t, Throwable e) {
System.out.println("CustomExceptionHandler uncaughtException e: " + e.getMessage());
defaultUEH.uncaughtException(t, e);
}
}
}
According to javadoc:
Sets the default uncaught exception handler. This handler is invoked in case any Thread dies due to an unhandled exception.
As far as I know in your case whole process is dying, that's why uncaughtException does not invoke. It will invoked if you will have uncaught exceptions inside separate threads.
public class X {
public void foo() throws Exception{
System.out.print("hi ");
throw new Exception();
}
public static void main(String[] args) throws Exception {
X c = new X();
c.foo();
}
}
As in my foo() method I am throwing Exception and propagating the Exception by using throws. In my main() method I am again propagating my Exception.
When I compile it works fine.
My question is: why don't I need to handle this throw new Exception()? Who is taking care of this?
It will be thrown to the err console as your
main method declares "throws Exception".
Remove this and it won't compile anymore.
Every thread has a handler for uncaught exceptions—exceptions that terminate the thread. The default exception handler invokes printStackTrace() on the Throwable that terminates the thread, unless the error is an instance of ThreadDeath. You can change this behavior on a particular thread by setting a custom handler, for a group of threads by extending ThreadGroup, or for all threads by installing a default handler.
It is sayed that the run does't throw Handled Exceptions. JVM simply ignores them. So I threw UnHandled Exception (ArithmeticException). But the same thing happened for it as well.
I know that it is rediculous to try to catch the excpetion from a thread that has been started by the catch clause marked as XXX. Because the excution may already passed that line.
But I wanna know why java allows run to throw Unhanlded Exception while restricting Handled ones and what is happening additionally when run() throwing Unhandled Exception?
Parent Thread
public class Parent {
public static void main(String[] args) {
Child child = new Child();
Thread chThread = new Thread(child);
try {
chThread.start();
} catch (Exception e) { // XXX mark
System.err.println("XXX");
e.printStackTrace();
}
}
Child Thread
public class Child implements Runnable {
#Override
public void run() throws ArithmeticException{
method0(); // line 8
}
public void method0(){
int i = 0/0; // line 12
}
}
java.lang.Thread
public class Thread implements Runnable {
public void run() {
if (target != null) {
target.run(); // line 619
}
}
}
StackTrace
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at seperateStacksPerThread.Child.method0(Child.java:12)
at seperateStacksPerThread.Child.run(Child.java:8)
at java.lang.Thread.run(Thread.java:619)
The signature of run() does not include a checked exception. As a result you can not override it to throw a checked exception (when you override you can never be more restrictive).
But throwing an unchecked exception is allowed as it is not part of the signature (no one is required to catch it).
When you throw the arithmetic exception it is part of the stack trace of a different thread.
Notice that it says:
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
And not: Exception in thread "main" java.lang.ArithmeticException: / by zero
Now why are checked exceptions not allowed, it is a design decision and I think it is because no one can catch them anyway as a thread is a separate flow of excecution.
Firstly, all methods may throw unchecked exceptions.
Next, the simple reason run() doesn't throw checked exceptions is there's no one there to catch them! The method is called from within the started thread as its "main" method - it's the top level entry point. There's nothing above it to deal with an exception, so there's no point in declaring a method that throws an exceptions.
Hey, I'm writing a network application, in which I read packets of some custom binary format. And I'm starting a background thread to wait for incoming data. The problem is, that the compiler doesn't let me to put any code throwing (checked) exceptions into run(). It says:
run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException
I want the exception to kill the thread, and let it be caught somewhere in the parent thread. Is this possible to achieve or do I have to handle every exception inside the thread?
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).
Caveat: this may not meet your needs if you have to use the exception mechanism.
If I understand you correctly, you don't actually need the exception to be checked (you've accepted the answer suggesting an unchecked exception) so would a simple listener pattern be more appropriate?
The listener could live in the parent thread, and when you've caught the checked exception in the child thread, you could simply notify the listener.
This means that you have a way of exposing that this will happen (through public methods), and will be able to pass more information than an exception will allow. But it does mean there will be a coupling (albeit a loose one) between the parent and the child thread. It would depend in your specific situation whether this would have a benefit over wrapping the checked exception with an unchecked one.
Here's a simple example (some code borrowed from another answer):
public class ThingRunnable implements Runnable {
private SomeListenerType listener;
// assign listener somewhere
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket();
}
} catch(Exception e) {
listener.notifyThatDarnedExceptionHappened(...);
}
}
}
The coupling comes from an object in the parent thread having to be of type SomeListenerType.
This answer is based on Esko Luontola one but it provides a working example.
Unlike the run() method of the Runnable interface the call() method of Callable allows to throw some exceptions. Here is an implementation example :
public class MyTask implements Callable<Integer> {
private int numerator;
private int denominator;
public MyTask(int n, int d) {
this.numerator = n;
this.denominator = d;
}
#Override
// The call method may throw an exception
public Integer call() throws Exception {
Thread.sleep(1000);
if (denominator == 0) {
throw new Exception("cannot devide by zero");
} else {
return numerator / denominator;
}
}
}
Executor provides a mechanism to run a Callable inside a thread and to handle any kind of exceptions :
public class Main {
public static void main(String[] args) {
// Build a task and an executor
MyTask task = new MyTask(2, 0);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
try {
// Start task on another thread
Future<Integer> futureResult = threadExecutor.submit(task);
// While task is running you can do asynchronous operations
System.out.println("Something that doesn't need the tasks result");
// Now wait until the result is available
int result = futureResult.get();
System.out.println("The result is " + result);
} catch (ExecutionException e) {
// Handle the exception thrown by the child thread
if (e.getMessage().contains("cannot devide by zero"))
System.out.println("error in child thread caused by zero division");
} catch (InterruptedException e) {
// This exception is thrown if the child thread is interrupted.
e.printStackTrace();
}
}
}
What I do is to catch the exception in the thread and store it as a member variable of the Runnable. This exception is then exposed via a getter on the Runnable. I then scan all the threads from the parent to see if any had exceptions, and take the appropriate action.
If you really cannot do anything useful when the exception is raised you can wrap the checked exception in a RuntimeException.
try {
// stuff
} catch (CheckedException yourCheckedException) {
throw new RuntimeException("Something to explain what is happening", yourCheckedException);
}
the thread can't throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
If your thread's code throw a RuntimeExpection, you doesn't need to add run() throw Exception.
But use this solution only when appropriate because this can be a bad pratice:
http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
Any RuntimeException or unchecked Exception can help you. Maybe you'll need to create your own RuntimeException
On the assumption that your code is in some kind of loop, you'd write:
public class ThingRunnable implements Runnable {
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket()
}
} catch(Exception e) {
System.out.println("Runnable terminating with exception" + e );
}
}
}
The exception will automatically break you out of your loop, and at the end of the run() method, the thread will stop.
Use this Runnable to create your Thread:
public abstract class TryRunner implements Runnable{
protected abstract void tryToRun();
protected void onException(Exception e){}
#Override
final public void run() {
try{ tryToRun(); }catch(Exception e){ e.printStackTrace(); onException(e); }
}
}
Wrapping your exception inside a RuntimeException seems to do the trick.
someMethod() throws IOException
{
try
{
new Thread(() ->
{
try
{
throw new IOException("a checked exception thrown from within a running thread");
}
catch(IOException ex)
{
throw new RuntimeException("a wrapper exception", ex); // wrap the checked exception inside an unchecked exception and throw it
}
}).start();
}
catch(RuntimeException ex) // catch the wrapped exception sent from within the thread
{
if(ex.getCause() instanceof IOException)
throw ex.getCause; // unwrap the checked exception using getCause method and use it however you need
else
throw ex;
}
}