001package jmri.util.exceptionhandler; 002 003import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 004 005import java.awt.GraphicsEnvironment; 006 007import jmri.util.swing.ExceptionContext; 008 009/** 010 * Class to log exceptions that rise to the top of threads, including to the top 011 * of the AWT event processing loop. 012 * 013 * Using code must install this with 014 * <pre> 015 * Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()); 016 * </pre> 017 * 018 * @author Bob Jacobsen Copyright 2003, 2010 019 */ 020public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { 021 022 @Override 023 public void uncaughtException(Thread t, Throwable e) { 024 025 // see http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadDeath.html 026 // 027 // The type ThreadDeath has been deprecated since version 20 and marked for removal 028 // and the warning cannot be suppressed in Java 21. But external libraries might 029 // throw the exception outside of JMRI control. So check the name of the exception 030 // instead of using "instanceof". 031 if ("java.lang.ThreadDeath".equals(e.getClass().getName())) { 032 log.info("Thread has stopped: {}", t.getName()); 033 return; 034 } 035 036 log.error("Uncaught Exception caught by jmri.util.exceptionhandler.UncaughtExceptionHandler", e); 037 038 if (e instanceof Error) { 039 if (!GraphicsEnvironment.isHeadless()) { 040 jmri.util.swing.ExceptionDisplayFrame.displayExceptionDisplayFrame(null, 041 new ErrorContext(e)); 042 } 043 log.error("System Exiting"); 044 systemExit(); 045 } 046 } 047 048 @SuppressFBWarnings(value="DM_EXIT", justification="Errors should terminate the application") 049 protected void systemExit(){ 050 System.exit(126); 051 } 052 053 private static class ErrorContext extends ExceptionContext { 054 055 public ErrorContext(@javax.annotation.Nonnull Throwable ex) { 056 super(ex, "", ""); 057 this.prefaceString = Bundle.getMessage("UnrecoverableErrorMessage"); 058 } 059 060 @Override 061 public String getTitle() { 062 return Bundle.getMessage("UnrecoverableErrorTitle"); 063 } 064 065 } 066 067 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(UncaughtExceptionHandler.class); 068 069}