diff --git a/spring-boot/src/main/java/org/springframework/boot/LoggedExceptionHandler.java b/spring-boot/src/main/java/org/springframework/boot/LoggedExceptionHandler.java index b673b7abde..be9dcdaad2 100644 --- a/spring-boot/src/main/java/org/springframework/boot/LoggedExceptionHandler.java +++ b/spring-boot/src/main/java/org/springframework/boot/LoggedExceptionHandler.java @@ -19,7 +19,10 @@ package org.springframework.boot; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * {@link UncaughtExceptionHandler} to suppress handling already logged exceptions. @@ -28,6 +31,14 @@ import java.util.List; */ class LoggedExceptionHandler implements UncaughtExceptionHandler { + private static Set LOG_CONFIGURATION_MESSAGES; + + static { + Set messages = new HashSet(); + messages.add("Logback configuration error detected"); + LOG_CONFIGURATION_MESSAGES = Collections.unmodifiableSet(messages); + } + private static LoggedExceptionHandlerThreadLocal handler = new LoggedExceptionHandlerThreadLocal(); private final UncaughtExceptionHandler parent; @@ -45,7 +56,7 @@ class LoggedExceptionHandler implements UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { try { - if (!isRegistered(ex) && this.parent != null) { + if (isPassedToParent(ex) && this.parent != null) { this.parent.uncaughtException(thread, ex); } } @@ -54,6 +65,26 @@ class LoggedExceptionHandler implements UncaughtExceptionHandler { } } + private boolean isPassedToParent(Throwable ex) { + return isLogConfigurationMessage(ex) || !isRegistered(ex); + } + + /** + * Check if the exception is a log configuration message, i.e. the log call might not + * have actually output anything. + */ + private boolean isLogConfigurationMessage(Throwable ex) { + String message = ex.getMessage(); + if (message != null) { + for (String candidate : LOG_CONFIGURATION_MESSAGES) { + if (message.contains(candidate)) { + return true; + } + } + } + return false; + } + private boolean isRegistered(Throwable ex) { if (this.exceptions.contains(ex)) { return true;