net.dclausen.util
Class UncaughtExceptionLogger

java.lang.Object
  extended byjava.lang.ThreadGroup
      extended bynet.dclausen.util.UncaughtExceptionLogger

public class UncaughtExceptionLogger
extends ThreadGroup

A ThreadGroup which logs its child Threads' uncaught exceptions using the java logging API. This overrides the default ThreadGroup behavior of printing the stack trace to System.err. This is particularly handy when dealing with threads started by libraries which are outside of your control. For example, when you have a Swing app and a misbehaving component is crashing the AWT event thread.

The recommended way to use this class is to construct an instance very early in your application's bootstrap process -- ideally before most classes are initialized -- and then continue your bootstrapping on a new child thread. The reason for doing this early on is because some classes start threads in their static initializers, and you probably want those threads to be owned by the UncaughtExceptionLogger. Even the java.util.logging.* classes can start threads, which is why the constructors for this class take String arguments rather than Logger and Level instances. Those names are resolved on a child thread.

UPDATE: As of Java 1.5, there is a better way of solving this problem. Take a look at ThreadGroup.setUncaughtExceptionHandler

Here is a simple example of how to bootstrap your app:

 
  ----------
      
  // MyAppLauncher.java
 
  // Keep it simple. Don't reference any unnecessary classes.
 
  public class MyAppLauncher {
 
     // Start a new thread which will have its (and all of its children's)
     // exceptions logged.  This thread will call MyApp.main(args)...
     public static void main(String[] args) {
         UncaughtExceptionLogger.invokeMain("", "WARNING", "MyApp", args);
     }
 
  }
  
  ----------     
       
  // MyApp.java
 
  import java.util.logging.*;
  import javax.swing.*;
  import oracle.jdbc.*;
 
  public class MyApp extends JFrame {
 
     public static void main(String[] args) {
         // Start the real app here. Initiaize classes, create threads, 
         // go crazy...
         MyApp app = new MyApp();
         ...
     }
 
  }
      
  ----------     
 
 

See Also:
Logger, Thread.run(), ThreadGroup.uncaughtException(java.lang.Thread, java.lang.Throwable)

Constructor Summary
UncaughtExceptionLogger(String loggerName, String levelName)
          Construct a new UncaughtExceptionLogger.
 
Method Summary
static void invokeMain(String loggerName, String levelName, String mainClass, String[] args)
          Construct a new UncaughtExceptionLogger, and invoke mainClass.main(args) on a child thread.
 void uncaughtException(Thread t, Throwable e)
          Log the Throwable using the java logging API.
 
Methods inherited from class java.lang.ThreadGroup
activeCount, activeGroupCount, allowThreadSuspension, checkAccess, destroy, enumerate, enumerate, enumerate, enumerate, getMaxPriority, getName, getParent, interrupt, isDaemon, isDestroyed, list, parentOf, resume, setDaemon, setMaxPriority, stop, suspend, toString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

UncaughtExceptionLogger

public UncaughtExceptionLogger(String loggerName,
                               String levelName)
Construct a new UncaughtExceptionLogger.

Parameters:
loggerName - the name of the logger to use; defaults to "" if null
levelName - the name of the logging level to use; defaults to "WARNING" if null
Method Detail

uncaughtException

public void uncaughtException(Thread t,
                              Throwable e)
Log the Throwable using the java logging API. This method is called by the JVM when a child thread's run() throws an Exception or Error.

See Also:
Thread.run()

invokeMain

public static void invokeMain(String loggerName,
                              String levelName,
                              String mainClass,
                              String[] args)
Construct a new UncaughtExceptionLogger, and invoke mainClass.main(args) on a child thread.

Parameters:
loggerName - the name of the logger to use
levelName - the name of the logging level to use
mainClass - the name of a class which contains a static main method
args - the arguments to pass to mainClass.main