Know the JVM Series – 1 – The Uncaught Exception Handler

The Java API, backed by the JVM provides tons of features and facilities to Java developers, which could be used to get things done easily for certain specific scenarios. However, these features are often overlooked by developers, mainly due to the lack of reading material and  resources regarding these APIs. The purpose of this article series is to introduce such features of the JVM and Java API to intermediate Java developers.

Most of the content that will be discussed as part of this series may not be applicable for your day to day work, but knowing this will enable to you to utilize these to get things done simply, and elegantly.

As first part of the series, we will be looking at the Uncaught Exception Handler API of the JVM.  Java uses (or in more specific terms, throws) exceptions to notify exceptional situations in programs. Developers write try-catch blocks to handle these exceptions, or simply propagate the exceptions upwards in the call stack. The uncaught exception handler allows developers to provide a code segment to be executed when an exception is propagated up the call stack, without being caught.This is helpful when we need to perform some operations when exceptions occur, such as in safety critical applications.

In order to explain how the uncaught exception handling mechanism works, we need to have an understanding about the structure of Java Exceptions. The class hierarchy of Java  Exceptions are as follows.

Java Exceptions Class Hierarchy

An uncaught exception is a Throwable, which is not caught by any part of the application in the call stack where the exception occurred. It has propagated through the call stack, and has arrived at the underlying thread (could be the main thread or a defined thread), without being caught. The usual default behavior is to write the stack trace to System.err output stream. But we can override this default behavior by providing our own uncaught exception handler, by extending the Thread.UncaughtExceptionHandler interface.

The interface requires us to implement a single method, as follows.

public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
  public void uncaughtException(Thread t, Throwable e) {
     // Write the custom logic here
   }
}

The first parameter, Thread t, is the thread in which the exception has occurred. The Throwable e, is the uncaught exception (or more specifically, the uncaught Throwable). You can provide any custom logic in this block, such as to write the error message to a specific log file, or to send an email indicating the error.

There are three places where this custom handler can be plugged in.

1. As the handler for a particular thread
When an uncaught exception occurs, the JVM initially looks for a handler registered for the particular thread. This can be set using Thread class method, public void setUncaughtExceptionHandler(handler) as in the following example.

public class MyRunnable implements Runnable {
   public void run() {
      // Other Code
      Thread.currentThread().setUncaughtExceptionHandler(myHandler);
      // Other Code
   }
}

2. As the handler for a particular thread group
If the thread belongs to a thread group, then the JVM attempts to invoke the handler for the thread group, if no thread level handler was specified (as in Option 1).

ThreadGroup class implements the Thread.UncaughtExceptionHandler interface. So we need to subclass the ThreadGroup class to provide an alternative implementation.

The default implementation of java.lang.ThreadGroup class does the following, in the given order.

  • If a parent thread group is present, invoke its uncaughtException method.
  • If no parent thread group, but if a Default Handler is specified (using Option 3 below), invoke the default handler
  • If no default handler is given, write the stack trace to system error. But if the exception is ThreadDeath error, ignore it (this is a special circumstance).

3. As the default handler for the application (JVM)
The default thread handler will be invoked by the JVM if no handler is present by any of the above steps. To set the default handler, Thread class provides a static method, which can be used as follows.

Thread.setDefaultUncaughtExceptionHandler(myHandler);

If none of the above are available, then the JVM delegates to its default behavior, writing to system error as specified in the ThreadGroup class. This is because main thread also belongs to the ‘main’ ThreadGroup, which uses the default implementation.

The uncaught exception handlers are useful in scenarios where certain actions should be taken when a failure occurs in the application, such as notifying to a particular email address, or to log to a specific file. Instead of writing try-catch blocks to cover such scenarios, a better solution would be to implement an Uncaught Exception Handler.

14 comments

  1. The uncaught exception handler is no doubt a good mechanism for handling such exceptions that the program may wish not to catch/handle, in such situations definitely the need arise for monitoring such exceptions for observing any unusual activities in the application. But the thing is that we need to do this for either per-thread or thread-group basis or in general for the process, the third option would lead us to situations where we have no control of which classes/packages we want to entertain for this methodology.

    For this we need some more controls on the scope for handling uncaught exceptions for the support/application monitoring team, I think AOP would help a lot better in these kind of situations where we can get fine-grained controls over the scope thing, although this doesn’t avoid writing try-catches in the application for manageable situations.

    The post is good.

    –Deepak

    1. Hi Deepak,

      Thanks for the reply.

      Yes, if we need fine grained control, AOP is the way to go. From my experience, I find the uncaught exception handler useful for notifying failure situations in mission-critical applications (a catch all scenario, to catch stuff like OutOfMemoryError etc). That would be the last line of defense against unexpected failures.

  2. thanks.
    By the way, you say, that one can create an OutOfMemoryError handler? Are you able to do anything in it? As there is not more memory for allocation available?

    1. Hi Martin,

      Sorry for the late response. Your message was flagged by WordPress as spam, so I missed it.

      Yes. If you write an uncaught exception handler, it will be invoked even for OutOfMemoryError scenarios. Your handler code will run, as far as there is free memory available for it to execute. Chances are that when the OOME is thrown, some memory is freed. Your handler can utilize this space and continue to work. But if during some point it does not have any more free memory to allocate, then at that particular line, a new OOME will be thrown (inside your handler). In this case, it will be propagated up, and the thread will crash.

    1. Hi Arun,

      Yes. You should be able to use this with in a Web Application. But a word of caution. If the Web Container already uses this for some purpose, then setting it (replacing it) by yourself might affect the functionality of the Web Container. To be safe, it’s better to delegate to the existing handler (if any) from your handler in such a scenario (use the relevant getter method).

      Also, if a SecurityManager is enforced, you need to have the permission to invoke this method. Otherwise it might result in SecurityException being thrown. See http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler)

  3. A very good detailed post. While reading the article, I got a question about what is the mechanism in jvm which handles the unhandled exceptions in a program? To explain it better I mean if in an standalone program, the main method itself includes checked exceptions like IOException in the throws clause, then the jvm still prints the stack trace if an IOException occurs during the exception. How is this done by the JVM?

    1. Hi Amit,

      If you look at the java.lang.Thread class code, there is a dispatchUncaughtException method. This method is invoked when an uncaught exception occurs with in a thread. What this method does is, it invokes the uncaught exception handler (if one exists), or delegates to the implementation provided by the ThreadGroup class.

      The ThreadGroup class itself implements the Thread.UncaughtExceptionHandler interface, and provides the default implementation used by the JVM.

      The implementation in Sun JDK is as follows :

      public void uncaughtException(Thread t, Throwable e) {
      	if (parent != null) {
      	    parent.uncaughtException(t, e);
      	} else {
                  Thread.UncaughtExceptionHandler ueh = 
                      Thread.getDefaultUncaughtExceptionHandler();
                  if (ueh != null) {
                      ueh.uncaughtException(t, e);
                  } else if (!(e instanceof ThreadDeath)) {
      		System.err.print("Exception in thread ""
      				 + t.getName() + "" ");
                      e.printStackTrace(System.err);
                  }
              }
          }
      

      This implementation prints the exception to System.out. That is how the exceptions thrown by the main method is handled.

  4. Hi Yohan,

    Does the setDefaultUncaughtExceptionHandler also works for GUI? I wrote a GUI, and added an exception handler, like follwoing:
    Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
    public void uncaughtException(Thread t, Throwable e) {
    if (e instanceof OutOfMemoryError) {
    //show error message

    }
    }
    The intention is to give user an error message before the system exits, because of OutOfMemoryError. But it is not as expected, the system always exits without showing any error message.

    Do you have any idea. Thank you for your hints in advance!

    1. Hi Selina,

      I have tried out catching the OutOfMemoryError under Sun JDK, and it works fine. I have commented on the same to Martin before. Quoting that,

      Yes. If you write an uncaught exception handler, it will be invoked even for OutOfMemoryError scenarios. Your handler code will run, as far as there is free memory available for it to execute. Chances are that when the OOME is thrown, some memory is freed. Your handler can utilize this space and continue to work. But if during some point it does not have any more free memory to allocate, then at that particular line, a new OOME will be thrown (inside your handler). In this case, it will be propagated up, and the thread will crash.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>