diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java index de48703a95..31512e2758 100644 --- a/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java +++ b/spring-boot/src/main/java/org/springframework/boot/logging/LoggingApplicationListener.java @@ -179,7 +179,8 @@ public class LoggingApplicationListener implements GenericApplicationListener { else if (event instanceof ApplicationPreparedEvent) { onApplicationPreparedEvent((ApplicationPreparedEvent) event); } - else if (event instanceof ContextClosedEvent) { + else if (event instanceof ContextClosedEvent && ((ContextClosedEvent) event) + .getApplicationContext().getParent() == null) { onContextClosedEvent(); } } diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/LoggingApplicationListenerTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/LoggingApplicationListenerTests.java index 882d89e5bf..eabd5480e9 100644 --- a/spring-boot/src/test/java/org/springframework/boot/logging/LoggingApplicationListenerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/logging/LoggingApplicationListenerTests.java @@ -42,6 +42,7 @@ import org.springframework.boot.test.EnvironmentTestUtils; import org.springframework.boot.test.OutputCapture; import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.test.util.ReflectionTestUtils; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.is; @@ -97,6 +98,7 @@ public class LoggingApplicationListenerTests { System.clearProperty("LOG_PATH"); System.clearProperty("PID"); System.clearProperty("LOG_EXCEPTION_CONVERSION_WORD"); + System.clearProperty(LoggingSystem.SYSTEM_PROPERTY); if (this.context != null) { this.context.close(); } @@ -386,6 +388,37 @@ public class LoggingApplicationListenerTests { TimeUnit.SECONDS), is(true)); } + @Test + public void closingContextCleansUpLoggingSystem() { + System.setProperty(LoggingSystem.SYSTEM_PROPERTY, + TestCleanupLoggingSystem.class.getName()); + this.initializer.onApplicationEvent( + new ApplicationStartedEvent(this.springApplication, new String[0])); + TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils + .getField(this.initializer, "loggingSystem"); + assertThat(loggingSystem.cleanedUp, is(false)); + this.initializer.onApplicationEvent(new ContextClosedEvent(this.context)); + assertThat(loggingSystem.cleanedUp, is(true)); + } + + @Test + public void closingChildContextDoesNotCleanUpLoggingSystem() { + System.setProperty(LoggingSystem.SYSTEM_PROPERTY, + TestCleanupLoggingSystem.class.getName()); + this.initializer.onApplicationEvent( + new ApplicationStartedEvent(this.springApplication, new String[0])); + TestCleanupLoggingSystem loggingSystem = (TestCleanupLoggingSystem) ReflectionTestUtils + .getField(this.initializer, "loggingSystem"); + assertThat(loggingSystem.cleanedUp, is(false)); + GenericApplicationContext childContext = new GenericApplicationContext(); + childContext.setParent(this.context); + this.initializer.onApplicationEvent(new ContextClosedEvent(childContext)); + assertThat(loggingSystem.cleanedUp, is(false)); + this.initializer.onApplicationEvent(new ContextClosedEvent(this.context)); + assertThat(loggingSystem.cleanedUp, is(true)); + childContext.close(); + } + private boolean bridgeHandlerInstalled() { Logger rootLogger = LogManager.getLogManager().getLogger(""); Handler[] handlers = rootLogger.getHandlers(); @@ -453,4 +486,34 @@ public class LoggingApplicationListenerTests { } + public static final class TestCleanupLoggingSystem extends LoggingSystem { + + private boolean cleanedUp = false; + + public TestCleanupLoggingSystem(ClassLoader classLoader) { + + } + + @Override + public void beforeInitialize() { + + } + + @Override + public void initialize(String configLocation, LogFile logFile) { + + } + + @Override + public void setLogLevel(String loggerName, LogLevel level) { + + } + + @Override + public void cleanUp() { + this.cleanedUp = true; + } + + } + }