From 8a0f0354dfed2fc6d4cb1b046ec03fe5b7ff1146 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 21 Jun 2018 11:18:08 +0100 Subject: [PATCH] Disable Log4J2's shutdown hook by default Log4J2 enables its shutdown hook by default. When the JVM is exiting, this creates a race between logging that happens during the application context being closed and Log4J2 being shut down such that the logging is lost. This commit updates SpringBootConfigurationFactory so that it produces a custom sub-class of DefaultConfiguration that disables the shutdown hook by default. In addition to solving the problem described above, this also aligns the Log4J2 logging system with the logging.register-shutdown-hook property which defaults to false. Closes gh-11360 --- .../SpringBootConfigurationFactory.java | 30 +++++++++---- .../SpringBootConfigurationFactoryTests.java | 44 +++++++++++++++++++ 2 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 spring-boot/src/test/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactoryTests.java diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactory.java b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactory.java index 4c39ebb2c9..b5f17c19f6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactory.java +++ b/spring-boot/src/main/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2016 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,12 +27,18 @@ import org.apache.logging.log4j.core.config.plugins.Plugin; import org.springframework.boot.logging.LoggingSystem; /** - * Spring Boot {@link ConfigurationFactory} that prevents logger warnings from being - * printed when the application first starts. This factory is ordered last and is - * triggered by a {@code log4j2.springboot} classpath resource (which is bundled in this - * jar). If the {@link Log4J2LoggingSystem} is active, a {@link DefaultConfiguration} is - * returned with the expectation that the system will later re-initialize Log4J2 with the - * correct configuration file. + * Spring Boot {@link ConfigurationFactory} that customizes Log4J2's default configuration + * to: + * + *
    + *
  1. Prevent logger warnings from being printed when the application first starts. + *
  2. Disable its shutdown hook + *
+ * + * This factory is ordered last and is triggered by a {@code log4j2.springboot} classpath + * resource (which is bundled in this jar). If the {@link Log4J2LoggingSystem} is active, + * a custom {@link DefaultConfiguration} is returned with the expectation that the system + * will later re-initialize Log4J2 with the correct configuration file. * * @author Phillip Webb * @since 1.5.0 @@ -53,10 +59,18 @@ public class SpringBootConfigurationFactory extends ConfigurationFactory { ConfigurationSource source) { if (source != null && source != ConfigurationSource.NULL_SOURCE) { if (LoggingSystem.get(loggerContext.getClass().getClassLoader()) != null) { - return new DefaultConfiguration(); + return new SpringBootConfiguration(); } } return null; } + private static final class SpringBootConfiguration extends DefaultConfiguration { + + private SpringBootConfiguration() { + this.isShutdownHookEnabled = false; + } + + } + } diff --git a/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactoryTests.java b/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactoryTests.java new file mode 100644 index 0000000000..f0babc7862 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/logging/log4j2/SpringBootConfigurationFactoryTests.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2018 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.logging.log4j2; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.ConfigurationSource; +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringBootConfigurationFactory}. + * + * @author Andy Wilkinson + */ +public class SpringBootConfigurationFactoryTests { + + @Test + public void producesConfigurationWithShutdownHookDisabled() throws IOException { + ConfigurationSource source = new ConfigurationSource( + new ByteArrayInputStream(new byte[0])); + assertThat(new SpringBootConfigurationFactory() + .getConfiguration(new LoggerContext(""), source).isShutdownHookEnabled()) + .isFalse(); + } + +}