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    }