001 package org.springframework.richclient.exceptionhandling;
002
003 import org.apache.commons.logging.LogFactory;
004
005 /**
006 * Uncaught exception handler designed to work with JDK 1.4 and 1.5's primitive API for registering
007 * exception handlers for the event thread.
008 *
009 * It's impossible to set an exception handler for the event thread in jdk 1.4 (and 1.5).
010 * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4714232
011 * So this effectively only works in Sun's JDK.
012 *
013 * @author Geoffrey De Smet
014 * @author Keith Donald
015 * @since 0.3
016 */
017 public class AwtExceptionHandlerAdapterHack {
018
019 private static final String SUN_AWT_EXCEPTION_HANDLER_KEY = "sun.awt.exception.handler";
020
021 /**
022 * Since Sun's JDK constructs the instance, its impossible to inject dependencies into it,
023 * except by a static reference like this.
024 */
025 private static RegisterableExceptionHandler exceptionHandlerDelegate = null;
026
027 /**
028 * Sets the {@link #SUN_AWT_EXCEPTION_HANDLER_KEY} system property to register this class as the event thread's
029 * exception handler. When called back, this class simply forwards to the delegate.
030 * @param exceptionHandlerDelegate the "real" exception handler to delegate to when an uncaught exception occurs.
031 */
032 public static void registerExceptionHandler(RegisterableExceptionHandler exceptionHandlerDelegate) {
033 AwtExceptionHandlerAdapterHack.exceptionHandlerDelegate = exceptionHandlerDelegate;
034 // Registers this class with the system properties so Sun's JDK can pick it up. Always sets even if previously set.
035 System.getProperties().put(SUN_AWT_EXCEPTION_HANDLER_KEY, AwtExceptionHandlerAdapterHack.class.getName());
036 }
037
038 /**
039 * No-arg constructor required so Sun's JDK can construct the instance.
040 */
041 public AwtExceptionHandlerAdapterHack() {
042 }
043
044 public void handle(Throwable throwable) {
045 if (exceptionHandlerDelegate == null) {
046 LogFactory.getLog(getClass()).error("No uncaughtExceptionHandler set while handling throwable.", throwable);
047 }
048 exceptionHandlerDelegate.uncaughtException(Thread.currentThread(), throwable);
049 }
050
051 }