Wednesday, October 22, 2014

Playing with Uncaught Exceptions in Java


Well, Once I got a scenario when someone asked me about Runtime Exceptions.  We know that Runtime Exception should not be caught using catch block. Rather it is handled by JVM. So JVM prints the stack trace and ends the program.

Is there any way to have little control on handling of these uncaught exceptions?



As in the above diagram, we can see the hierarchy of exceptions in Java. There could be 2 scenario when an exception could be uncaught.
   

  1.     Using Try – finally block without Catch : So here exception is not caught and it  is automatically propagated to upper call hierarchy to handle it and finally reaches to JVM
  2.    Occurrence of RunTime Exceptions which are directly handled by JVM.

In both the cases above JVM exception handler will take care of this.
Java provides a beautiful API to have little control over Uncaught Exception handling before JVM does it. This is Uncaught Exception Handler API of JVM.

Think of a scenario where you want an email or sms to be sent to some concerned persons or any other application to be invoked,  etc just when a uncaught exception or runtime exception occurs and JVM terminates the program. At this point you would be needing some hook point where you can process your customization and get noticed. This can be provided by implementing Thread.UncaughtExceptionHandler.
So create a Class which would implement Thread.UncaughtExceptionHandler and then use Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
Let’s understand this with an example.
public class TestUncaughtException {

       public static void main(String[] args) {
              Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
              //try{
                     int i = 0;
                    
                     System.out.println(50/i);
                     System.out.println("hello");
       //     }
              /*catch(Exception e){
                     System.out.println("in catch");
              }
              finally{
                     System.out.println("divide by zero");
              }*/
       }
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{

       @Override
       public void uncaughtException(Thread t, Throwable e) {
              System.out.println("in handler");
              //System.out.println(e.getMessage());
              //e.printStackTrace();
              // Custom code to do any extra processing
              Thread.currentThread().getThreadGroup().uncaughtException(t, e);
       }
      
}

Code above seems to be self-explanatoryMyUncaughtExceptionHandler is my custom hanlder which implements Thread.UncaughtExceptionHandler.
Write your customizations in uncaughtException(Thread t, Throwable e) method.
Who is invoking this method. Yes, it is JVM. JVM calls Thread.dispatchUncaughtException(Throwable e).

/**
     * Dispatch an uncaught exception to the handler. This method is
     * intended to be called only by the JVM.
     */
    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }


If this JVM does not finds any UncaughtExceptionHandler set in specific thread then it calls ThreadGroup. uncaughtException(Thread t, Throwable e). 

Java Doc of this method says : 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.

And finally if this ThreadGroup is also not able to handle this uncaught exception then it is handled by defaultUncaughtExceptionHandler. Which is set by Thread. setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh).

Java Doc for this says: Set the default handler invoked when a thread abruptly terminates due to an uncaught exception, and no other handler has been defined for that thread. Uncaught exception handling is controlled first by the thread, then by the thread's ThreadGroup object and finally by the default uncaught exception handler. If the thread does not have an explicit uncaught exception handler set, and the thread's thread group (including parent thread groups) does not specialize its uncaughtException method, then the default handler's uncaughtException method will be invoked.

If you want to have more control on handling these exceptions then you can try AOP which has got extra features to do it. But this hook provided by JVM to have little control over it makes life easier enough.

Hope you like this article. Queries and suggestions are most welcome.


CHEERS!!!