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