LOG4J2-1606 LOG4J2-2624 Add flag to disable automatic log4j shutdown in log4j-web. (#463)
diff --git a/log4j-web/pom.xml b/log4j-web/pom.xml
index 3ce1f93..f321fa0 100644
--- a/log4j-web/pom.xml
+++ b/log4j-web/pom.xml
@@ -61,14 +61,18 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.junit.vintage</groupId>
- <artifactId>junit-vintage-engine</artifactId>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-all</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</dependency>
<dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContainerInitializer.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContainerInitializer.java
index 19ac246..eda3853 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContainerInitializer.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContainerInitializer.java
@@ -57,7 +57,10 @@
initializer.start();
initializer.setLoggerContext(); // the application is just now starting to start up
- servletContext.addListener(new Log4jServletContextListener());
+ if (!"true".equalsIgnoreCase(servletContext.getInitParameter(
+ Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED))) {
+ servletContext.addListener(new Log4jServletContextListener());
+ }
filter.setAsyncSupported(true); // supporting async when the user isn't using async has no downsides
filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContextListener.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContextListener.java
index a121ccf..af756e3 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContextListener.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jServletContextListener.java
@@ -24,7 +24,6 @@
import javax.servlet.ServletContextListener;
import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.LifeCycle;
import org.apache.logging.log4j.core.LifeCycle2;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;
@@ -51,6 +50,14 @@
public void contextInitialized(final ServletContextEvent event) {
this.servletContext = event.getServletContext();
LOGGER.debug("Log4jServletContextListener ensuring that Log4j starts up properly.");
+
+ if ("true".equalsIgnoreCase(servletContext.getInitParameter(
+ Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED))) {
+ throw new IllegalStateException("Do not use " + getClass().getSimpleName() + " when "
+ + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
+ + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
+ + getClass().getSimpleName() + ".");
+ }
this.initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext);
try {
@@ -71,12 +78,16 @@
this.initializer.clearLoggerContext(); // the application is finished
// shutting down now
- final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
- final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
- : Long.parseLong(stopTimeoutStr);
- final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
- final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
- : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
- ((LifeCycle) this.initializer).stop(stopTimeout, timeoutTimeUnit);
+ if (initializer instanceof LifeCycle2) {
+ final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
+ final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
+ : Long.parseLong(stopTimeoutStr);
+ final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
+ final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
+ : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
+ ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
+ } else {
+ this.initializer.stop();
+ }
}
}
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListener.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListener.java
new file mode 100644
index 0000000..9bbe9c1
--- /dev/null
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListener.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.web;
+
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LifeCycle2;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
+
+public class Log4jShutdownOnContextDestroyedListener implements ServletContextListener {
+
+ private static final int DEFAULT_STOP_TIMEOUT = 30;
+ private static final TimeUnit DEFAULT_STOP_TIMEOUT_TIMEUNIT = TimeUnit.SECONDS;
+
+ private static final String KEY_STOP_TIMEOUT = "log4j.stop.timeout";
+ private static final String KEY_STOP_TIMEOUT_TIMEUNIT = "log4j.stop.timeout.timeunit";
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ private ServletContext servletContext;
+ private Log4jWebLifeCycle initializer;
+
+ @Override
+ public void contextInitialized(final ServletContextEvent event) {
+ LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
+ " ensuring that Log4j started up properly.");
+ servletContext = event.getServletContext();
+ if (null == servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)) {
+ throw new IllegalStateException(
+ "Context did not contain required Log4jWebLifeCycle in the "
+ + Log4jWebSupport.SUPPORT_ATTRIBUTE + " attribute.");
+ }
+ this.initializer = WebLoggerContextUtils.getWebLifeCycle(servletContext);
+ }
+
+ @Override
+ public void contextDestroyed(final ServletContextEvent event) {
+ if (this.servletContext == null || this.initializer == null) {
+ LOGGER.warn("Context destroyed before it was initialized.");
+ return;
+ }
+ LOGGER.debug(Log4jShutdownOnContextDestroyedListener.class.getSimpleName() +
+ " ensuring that Log4j shuts down properly.");
+
+ this.initializer.clearLoggerContext(); // the application is finished
+ // shutting down now
+ if (initializer instanceof LifeCycle2) {
+ final String stopTimeoutStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT);
+ final long stopTimeout = Strings.isEmpty(stopTimeoutStr) ? DEFAULT_STOP_TIMEOUT
+ : Long.parseLong(stopTimeoutStr);
+ final String timeoutTimeUnitStr = servletContext.getInitParameter(KEY_STOP_TIMEOUT_TIMEUNIT);
+ final TimeUnit timeoutTimeUnit = Strings.isEmpty(timeoutTimeUnitStr) ? DEFAULT_STOP_TIMEOUT_TIMEUNIT
+ : TimeUnit.valueOf(timeoutTimeUnitStr.toUpperCase(Locale.ROOT));
+ ((LifeCycle2) this.initializer).stop(stopTimeout, timeoutTimeUnit);
+ } else {
+ this.initializer.stop();
+ }
+ }
+}
diff --git a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebSupport.java b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebSupport.java
index c611a16..22ed45d 100644
--- a/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebSupport.java
+++ b/log4j-web/src/main/java/org/apache/logging/log4j/web/Log4jWebSupport.java
@@ -56,6 +56,13 @@
String IS_LOG4J_AUTO_INITIALIZATION_DISABLED = "isLog4jAutoInitializationDisabled";
/**
+ * The {@link javax.servlet.ServletContext} parameter name for the flag that disables Log4j's auto-shutdown
+ * in Servlet 3.0+ web applications. Set a context parameter with this name to "true" to disable
+ * auto-shutdown.
+ */
+ String IS_LOG4J_AUTO_SHUTDOWN_DISABLED = "isLog4jAutoShutdownDisabled";
+
+ /**
* The attribute key for the {@link javax.servlet.ServletContext} attribute that the singleton support instance
* is stored in.
*/
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContainerInitializerTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContainerInitializerTest.java
index 0cd3988..7b61f1c 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContainerInitializerTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContainerInitializerTest.java
@@ -24,22 +24,24 @@
import javax.servlet.ServletContext;
import org.apache.logging.log4j.util.Strings;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.any;
import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.never;
import static org.mockito.BDDMockito.then;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
public class Log4jServletContainerInitializerTest {
@Mock
private ServletContext servletContext;
@@ -52,7 +54,7 @@
private Log4jServletContainerInitializer containerInitializer;
- @Before
+ @BeforeEach
public void setUp() {
this.containerInitializer = new Log4jServletContainerInitializer();
}
@@ -83,6 +85,29 @@
}
@Test
+ public void testOnStartupWithServletVersion3_xEffectiveVersion3_xShutdownDisabled() throws Exception {
+ final FilterRegistration.Dynamic registration = mock(FilterRegistration.Dynamic.class);
+ given(servletContext.getMajorVersion()).willReturn(3);
+ given(servletContext.getEffectiveMajorVersion()).willReturn(3);
+ given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED)))
+ .willReturn("true");
+ given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_AUTO_INITIALIZATION_DISABLED))).willReturn(
+ null);
+ given(servletContext.addFilter(eq("log4jServletFilter"), filterCaptor.capture())).willReturn(registration);
+ given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)).willReturn(initializer);
+
+ this.containerInitializer.onStartup(null, this.servletContext);
+
+ then(initializer).should().start();
+ then(initializer).should().setLoggerContext();
+ then(registration).should().setAsyncSupported(eq(true));
+ then(registration).should().addMappingForUrlPatterns(eq(EnumSet.allOf(DispatcherType.class)), eq(false), eq("/*"));
+
+ // initParam IS_LOG4J_AUTO_SHUTDOWN_DISABLED is "true" so addListener shouldn't be called.
+ then(servletContext).should(never()).addListener(any(Log4jServletContextListener.class));
+ }
+
+ @Test
public void testOnStartupWithServletVersion3_xEffectiveVersion3_xDisabledTRUE() throws Exception {
given(servletContext.getMajorVersion()).willReturn(3);
given(servletContext.getEffectiveMajorVersion()).willReturn(3);
@@ -110,12 +135,13 @@
then(registration).should().setAsyncSupported(eq(true));
then(registration).should().addMappingForUrlPatterns(eq(EnumSet.allOf(DispatcherType.class)), eq(false), eq("/*"));
- assertNotNull("The listener should not be null.", listenerCaptor.getValue());
- assertSame("The listener is not correct.", Log4jServletContextListener.class,
- listenerCaptor.getValue().getClass());
+ assertNotNull(listenerCaptor.getValue(), "The listener should not be null.");
+ assertSame(Log4jServletContextListener.class,
+ listenerCaptor.getValue().getClass(),
+ "The listener is not correct.");
- assertNotNull("The filter should not be null.", filterCaptor.getValue());
- assertSame("The filter is not correct.", Log4jServletFilter.class, filterCaptor.getValue());
+ assertNotNull(filterCaptor.getValue(), "The filter should not be null.");
+ assertSame(Log4jServletFilter.class, filterCaptor.getValue(), "The filter is not correct.");
}
@Test
@@ -128,8 +154,8 @@
this.containerInitializer.onStartup(null, this.servletContext);
- assertNotNull("The filter should not be null.", filterCaptor.getValue());
- assertSame("The filter is not correct.", Log4jServletFilter.class, filterCaptor.getValue());
+ assertNotNull(filterCaptor.getValue(), "The filter should not be null.");
+ assertSame(Log4jServletFilter.class, filterCaptor.getValue(), "The filter is not correct.");
}
@Test
@@ -148,11 +174,11 @@
this.containerInitializer.onStartup(null, this.servletContext);
fail("Expected the exception thrown by the initializer; got no exception.");
} catch (final IllegalStateException e) {
- assertSame("The exception is not correct.", exception, e);
+ assertSame(exception, e, "The exception is not correct.");
}
then(initializer).should().start();
- assertNotNull("The filter should not be null.", filterCaptor.getValue());
- assertSame("The filter is not correct.", Log4jServletFilter.class, filterCaptor.getValue());
+ assertNotNull(filterCaptor.getValue(), "The filter should not be null.");
+ assertSame(Log4jServletFilter.class, filterCaptor.getValue(), "The filter is not correct.");
}
}
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContextListenerTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContextListenerTest.java
index 1dbc75d..35d662d 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContextListenerTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletContextListenerTest.java
@@ -20,31 +20,33 @@
import javax.servlet.ServletContextEvent;
import org.apache.logging.log4j.util.Strings;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.BDDMockito.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.BDDMockito.willThrow;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
public class Log4jServletContextListenerTest {
- @Mock
- private ServletContextEvent event;
- @Mock
+ /* event and servletContext are marked lenient because they aren't used in the
+ * testDestroyWithNoInit but are only accessed during initialization
+ */
+ @Mock(lenient = true)
+ private ServletContextEvent event;
+ @Mock(lenient = true)
private ServletContext servletContext;
@Mock
private Log4jWebLifeCycle initializer;
private Log4jServletContextListener listener;
- @Before
+ @BeforeEach
public void setUp() {
this.listener = new Log4jServletContextListener();
given(event.getServletContext()).willReturn(servletContext);
@@ -61,7 +63,7 @@
this.listener.contextDestroyed(this.event);
then(initializer).should().clearLoggerContext();
- then(initializer).should().stop(30L, TimeUnit.SECONDS);
+ then(initializer).should().stop();
}
@Test
@@ -72,8 +74,36 @@
this.listener.contextInitialized(this.event);
fail("Expected a RuntimeException.");
} catch (final RuntimeException e) {
- assertEquals("The message is not correct.", "Failed to initialize Log4j properly.", e.getMessage());
+ assertEquals("Failed to initialize Log4j properly.", e.getMessage(), "The message is not correct.");
}
}
+ @Test
+ public void initializingLog4jServletContextListenerShouldFaileWhenAutoShutdownIsTrue() throws Exception {
+ given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED)))
+ .willReturn("true");
+ ensureInitializingFailsWhenAuthShutdownIsEnabled();
+ }
+
+ @Test
+ public void initializingLog4jServletContextListenerShouldFaileWhenAutoShutdownIsTRUE() throws Exception {
+ given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED)))
+ .willReturn("TRUE");
+ ensureInitializingFailsWhenAuthShutdownIsEnabled();
+ }
+
+ private void ensureInitializingFailsWhenAuthShutdownIsEnabled() {
+ try {
+ this.listener.contextInitialized(this.event);
+ fail("Expected a RuntimeException.");
+ } catch (final RuntimeException e) {
+ String expectedMessage =
+ "Do not use " + Log4jServletContextListener.class.getSimpleName() + " when "
+ + Log4jWebSupport.IS_LOG4J_AUTO_SHUTDOWN_DISABLED + " is true. Please use "
+ + Log4jShutdownOnContextDestroyedListener.class.getSimpleName() + " instead of "
+ + Log4jServletContextListener.class.getSimpleName() + ".";
+
+ assertEquals(expectedMessage, e.getMessage(), "The message is not correct");
+ }
+ }
}
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletFilterTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletFilterTest.java
index 1fb72a3..479ac26 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletFilterTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jServletFilterTest.java
@@ -22,23 +22,24 @@
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.BeforeEach;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.reset;
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
public class Log4jServletFilterTest {
- @Mock
+ @Mock(lenient = true) // because filterConfig is not used in testDestroy
private FilterConfig filterConfig;
- @Mock
+ @Mock(lenient = true) // because filterConfig is not used in testDestroy
private ServletContext servletContext;
@Mock
private Log4jWebLifeCycle initializer;
@@ -51,7 +52,7 @@
private Log4jServletFilter filter;
- @Before
+ @BeforeEach
public void setUp() {
given(filterConfig.getServletContext()).willReturn(servletContext);
given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)).willReturn(initializer);
@@ -69,9 +70,11 @@
then(initializer).should().setLoggerContext();
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testDestroy() {
- this.filter.destroy();
+ assertThrows(IllegalStateException.class, () -> {
+ this.filter.destroy();
+ });
}
@Test
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListenerTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListenerTest.java
new file mode 100644
index 0000000..5577381
--- /dev/null
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jShutdownOnContextDestroyedListenerTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.logging.log4j.web;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.never;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class Log4jShutdownOnContextDestroyedListenerTest {
+ @Mock(lenient = true)
+ private ServletContextEvent event;
+ @Mock(lenient = true)
+ private ServletContext servletContext;
+ @Mock
+ private Log4jWebLifeCycle initializer;
+
+ private Log4jShutdownOnContextDestroyedListener listener;
+
+ public void setUp(boolean mockInitializer) {
+ this.listener = new Log4jShutdownOnContextDestroyedListener();
+ given(event.getServletContext()).willReturn(servletContext);
+ if (mockInitializer) {
+ given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE))
+ .willReturn(initializer);
+ }
+ }
+
+ @Test
+ public void testInitAndDestroy() throws Exception {
+ setUp(true);
+ this.listener.contextInitialized(this.event);
+
+ then(initializer).should(never()).start();
+ then(initializer).should(never()).setLoggerContext();
+
+ this.listener.contextDestroyed(this.event);
+
+ then(initializer).should().clearLoggerContext();
+ then(initializer).should().stop();
+ }
+
+ @Test
+ public void testDestroy() throws Exception {
+ setUp(true);
+ this.listener.contextDestroyed(this.event);
+
+ then(initializer).should(never()).clearLoggerContext();
+ then(initializer).should(never()).stop();
+ }
+
+ @Test
+ public void whenNoInitializerInContextTheContextInitializedShouldThrowAnException() {
+ setUp(false);
+
+ assertThrows(IllegalStateException.class, () -> {
+ this.listener.contextInitialized(this.event);
+ });
+ }
+}
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
index 71d0cf2..40e10df 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/Log4jWebInitializerImplTest.java
@@ -24,83 +24,80 @@
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.composite.CompositeConfiguration;
import org.apache.logging.log4j.core.impl.ContextAnchor;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
-@RunWith(MockitoJUnitRunner.class)
+@ExtendWith(MockitoExtension.class)
public class Log4jWebInitializerImplTest {
- @Mock
- private ServletContext servletContext;
+ /* Marking servletContext lenient because otherwise testCompositeLocationParameterWithEmptyUriListSetsDefaultConfiguration fails
+ * when null is passed in as the initial param because Mockito deciced null isn't a String rather than the absence of a string.
+ */
+ @Mock(lenient = true)
+ private ServletContext servletContext;
@Captor
private ArgumentCaptor<Log4jWebLifeCycle> initializerCaptor;
@Captor
private ArgumentCaptor<LoggerContext> loggerContextCaptor;
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
private Log4jWebInitializerImpl initializerImpl;
- @Before
+ @BeforeEach
public void setUp() {
given(servletContext.getAttribute(Log4jWebSupport.SUPPORT_ATTRIBUTE)).willReturn(null);
final Log4jWebLifeCycle initializer = WebLoggerContextUtils.getWebLifeCycle(this.servletContext);
then(servletContext).should().setAttribute(eq(Log4jWebSupport.SUPPORT_ATTRIBUTE), initializerCaptor.capture());
- assertNotNull("The initializer should not be null.", initializer);
- assertSame("The capture is not correct.", initializer, initializerCaptor.getValue());
- assertTrue("The initializer is not correct.", initializer instanceof Log4jWebInitializerImpl);
+ assertNotNull(initializer, "The initializer should not be null.");
+ assertSame(initializer, initializerCaptor.getValue(), "The capture is not correct.");
+ assertTrue(initializer instanceof Log4jWebInitializerImpl, "The initializer is not correct.");
this.initializerImpl = (Log4jWebInitializerImpl) initializer;
}
@Test
public void testDeinitializeBeforeInitialize() {
- expectedException.expect(IllegalStateException.class);
- this.initializerImpl.stop();
+ assertThrows(IllegalStateException.class, () -> {
+ this.initializerImpl.stop();
+ });
}
@Test
public void testSetLoggerContextBeforeInitialize() {
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
}
@Test
public void testClearLoggerContextBeforeInitialize() {
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.clearLoggerContext();
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
}
@Test
- public void testInitializeWithNoParametersThenSetLoggerContextThenDeinitialize() throws Exception {
+ public void testInitializeWithNoParametersThenSetLoggerContextThenDeinitialize() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn(null);
@@ -110,85 +107,85 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
final org.apache.logging.log4j.spi.LoggerContext loggerContext = loggerContextCaptor.getValue();
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
this.initializerImpl.setLoggerContext();
final LoggerContext context = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("The context should not be null.", context);
- assertSame("The context is not correct.", loggerContext, context);
+ assertNotNull(context, "The context should not be null.");
+ assertSame(loggerContext, context, "The context is not correct.");
this.initializerImpl.clearLoggerContext();
- assertNull("The context should be null again.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null again.");
this.initializerImpl.stop();
then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
- assertNull("The context should again still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should again still be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should finally still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should finally still be null.");
}
@Test
- public void testInitializeWithClassLoaderNoParametersThenSetLoggerContextThenDeinitialize() throws Exception {
+ public void testInitializeWithClassLoaderNoParametersThenSetLoggerContextThenDeinitialize() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn("false");
given(servletContext.getServletContextName()).willReturn("helloWorld02");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
given(servletContext.getClassLoader()).willReturn(getClass().getClassLoader());
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
final org.apache.logging.log4j.spi.LoggerContext loggerContext = loggerContextCaptor.getValue();
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
this.initializerImpl.setLoggerContext();
final LoggerContext context = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("The context should not be null.", context);
- assertSame("The context is not correct.", loggerContext, context);
+ assertNotNull(context, "The context should not be null.");
+ assertSame(loggerContext, context, "The context is not correct.");
this.initializerImpl.clearLoggerContext();
- assertNull("The context should be null again.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null again.");
this.initializerImpl.stop();
then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
- assertNull("The context should again still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should again still be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should finally still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should finally still be null.");
}
@Test
- public void testInitializeIsIdempotent() throws Exception {
+ public void testInitializeIsIdempotent() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn("nothing");
given(servletContext.getServletContextName()).willReturn("helloWorld03");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
given(servletContext.getClassLoader()).willReturn(getClass().getClassLoader());
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
this.initializerImpl.start();
this.initializerImpl.start();
@@ -199,42 +196,43 @@
}
@Test
- public void testInitializeFailsAfterDeinitialize() throws Exception {
+ public void testInitializeFailsAfterDeinitialize() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn(null);
given(servletContext.getServletContextName()).willReturn("helloWorld04");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
given(servletContext.getClassLoader()).willReturn(getClass().getClassLoader());
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
this.initializerImpl.stop();
then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
- expectedException.expect(IllegalStateException.class);
- this.initializerImpl.start();
+ assertThrows(IllegalStateException.class, () -> {
+ this.initializerImpl.start();
+ });
}
@Test
- public void testDeinitializeIsIdempotent() throws Exception {
+ public void testDeinitializeIsIdempotent() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn(null);
given(servletContext.getServletContextName()).willReturn("helloWorld05");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
given(servletContext.getClassLoader()).willReturn(getClass().getClassLoader());
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
this.initializerImpl.stop();
this.initializerImpl.stop();
@@ -243,88 +241,86 @@
}
@Test
- public void testInitializeUsingJndiSelectorFails() throws Exception {
+ public void testInitializeUsingJndiSelectorFails() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn("true");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
- expectedException.expect(IllegalStateException.class);
- this.initializerImpl.start();
+ assertThrows(IllegalStateException.class, () -> {
+ this.initializerImpl.start();
+ });
}
@Test
- public void testInitializeUsingJndiSelector() throws Exception {
+ public void testInitializeUsingJndiSelector() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn("helloWorld06");
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn("true");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNull("The context attribute should be null.", loggerContextCaptor.getValue());
+ assertNull(loggerContextCaptor.getValue(), "The context attribute should be null.");
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should still be null because no named selector.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null because no named selector.");
this.initializerImpl.clearLoggerContext();
- assertNull("The context should be null again.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null again.");
this.initializerImpl.stop();
- assertNull("The context should again still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should again still be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should finally still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should finally still be null.");
}
@Test
- public void testWrapExecutionWithNoParameters() throws Exception {
+ public void testWrapExecutionWithNoParameters() {
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONTEXT_NAME))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.LOG4J_CONFIG_LOCATION))).willReturn(null);
given(servletContext.getInitParameter(eq(Log4jWebSupport.IS_LOG4J_CONTEXT_SELECTOR_NAMED))).willReturn(null);
given(servletContext.getServletContextName()).willReturn("helloWorld07");
given(servletContext.getResourcePaths("/WEB-INF/")).willReturn(null);
- assertNull("The context should be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null.");
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
final org.apache.logging.log4j.spi.LoggerContext loggerContext = loggerContextCaptor.getValue();
- assertNull("The context should still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should still be null.");
- final Runnable runnable = new Runnable() {
- @Override
- public void run() {
- final LoggerContext context = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("The context should not be null.", context);
- assertSame("The context is not correct.", loggerContext, context);
- }
+ final Runnable runnable = () -> {
+ final LoggerContext context = ContextAnchor.THREAD_CONTEXT.get();
+ assertNotNull(context, "The context should not be null.");
+ assertSame(loggerContext, context, "The context is not correct.");
};
this.initializerImpl.wrapExecution(runnable);
- assertNull("The context should be null again.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should be null again.");
this.initializerImpl.stop();
then(servletContext).should().removeAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE));
- assertNull("The context should again still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should again still be null.");
this.initializerImpl.setLoggerContext();
- assertNull("The context should finally still be null.", ContextAnchor.THREAD_CONTEXT.get());
+ assertNull(ContextAnchor.THREAD_CONTEXT.get(), "The context should finally still be null.");
}
@Test
@@ -334,7 +330,7 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
assertThat(loggerContextCaptor.getValue().getConfigLocation(), is(nullValue()));
@@ -349,7 +345,7 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
assertThat(loggerContextCaptor.getValue().getConfigLocation(), is(URI.create("file:/a/b/c/WEB-INF/log4j2.xml")));
@@ -367,7 +363,7 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
assertThat(loggerContextCaptor.getValue().getConfigLocation(),
is(URI.create("file:/a/b/c/WEB-INF/log4j2-mycontext.xml")));
@@ -382,7 +378,7 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
assertThat(loggerContextCaptor.getValue().getConfiguration(), is(instanceOf(DefaultConfiguration.class)));
@@ -398,7 +394,7 @@
this.initializerImpl.start();
then(servletContext).should().setAttribute(eq(Log4jWebSupport.CONTEXT_ATTRIBUTE), loggerContextCaptor.capture());
- assertNotNull("The context attribute should not be null.", loggerContextCaptor.getValue());
+ assertNotNull(loggerContextCaptor.getValue(), "The context attribute should not be null.");
assertThat(loggerContextCaptor.getValue().getConfiguration(), is(instanceOf(CompositeConfiguration.class)));
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/PropertyTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/PropertyTest.java
index d17f495..40945c2 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/PropertyTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/PropertyTest.java
@@ -19,9 +19,9 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.impl.Log4jContextFactory;
import org.apache.logging.log4j.util.Constants;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
/**
*
@@ -31,12 +31,12 @@
@Test
public void testShutdownHookDisabled() {
assertFalse(
- "Shutdown hook should be disabled by default in web applications",
- ((Log4jContextFactory) LogManager.getFactory()).isShutdownHookEnabled());
+ ((Log4jContextFactory) LogManager.getFactory()).isShutdownHookEnabled(),
+ "Shutdown hook should be disabled by default in web applications");
}
@Test
public void testIsWebApp() {
- assertTrue("When servlet classes are available IS_WEB_APP should default to true", Constants.IS_WEB_APP);
+ assertTrue(Constants.IS_WEB_APP, "When servlet classes are available IS_WEB_APP should default to true");
}
}
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
index bb7147c..0317b02 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/ServletAppenderTest.java
@@ -24,10 +24,10 @@
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.impl.ContextAnchor;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockServletContext;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
/**
*
@@ -50,12 +50,12 @@
initializer.start();
initializer.setLoggerContext();
final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("No LoggerContext", ctx);
- assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
+ assertNotNull(ctx, "No LoggerContext");
+ assertNotNull(WebLoggerContextUtils.getServletContext(), "No ServletContext");
final Configuration configuration = ctx.getConfiguration();
- assertNotNull("No configuration", configuration);
+ assertNotNull(configuration, "No configuration");
final Appender appender = configuration.getAppender("Servlet");
- assertNotNull("No ServletAppender", appender);
+ assertNotNull(appender, "No ServletAppender");
final Logger logger = LogManager.getLogger("Test");
logger.info("This is a test");
logger.error("This is a test 2", new IllegalStateException().fillInStackTrace());
diff --git a/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java b/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
index 398c4b4..e2c8ded 100644
--- a/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
+++ b/log4j-web/src/test/java/org/apache/logging/log4j/web/WebLookupTest.java
@@ -26,11 +26,11 @@
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.impl.ContextAnchor;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
public class WebLookupTest {
@@ -48,27 +48,27 @@
initializer.start();
initializer.setLoggerContext();
final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("No LoggerContext", ctx);
- assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
+ assertNotNull(ctx, "No LoggerContext");
+ assertNotNull(WebLoggerContextUtils.getServletContext(), "No ServletContext");
final Configuration config = ctx.getConfiguration();
- assertNotNull("No Configuration", config);
+ assertNotNull(config, "No Configuration");
final StrSubstitutor substitutor = config.getStrSubstitutor();
- assertNotNull("No Interpolator", substitutor);
+ assertNotNull(substitutor, "No Interpolator");
String value = substitutor.replace("${web:initParam.TestParam}");
- assertNotNull("No value for TestParam", value);
- assertEquals("Incorrect value for TestParam: " + value, "ParamValue", value);
+ assertNotNull(value, "No value for TestParam");
+ assertEquals("ParamValue", value, "Incorrect value for TestParam: " + value);
value = substitutor.replace("${web:attr.TestAttr}");
- assertNotNull("No value for TestAttr", value);
- assertEquals("Incorrect value for TestAttr: " + value, "AttrValue", value);
+ assertNotNull(value, "No value for TestAttr");
+ assertEquals("AttrValue", value, "Incorrect value for TestAttr: " + value);
value = substitutor.replace("${web:Name1}");
- assertNotNull("No value for Name1", value);
- assertEquals("Incorrect value for Name1: " + value, "Ben", value);
+ assertNotNull(value, "No value for Name1");
+ assertEquals("Ben", value, "Incorrect value for Name1: " + value);
value = substitutor.replace("${web:Name2}");
- assertNotNull("No value for Name2", value);
- assertEquals("Incorrect value for Name2: " + value, "Jerry", value);
+ assertNotNull(value, "No value for Name2");
+ assertEquals("Jerry", value, "Incorrect value for Name2: " + value);
value = substitutor.replace("${web:contextPathName}");
- assertNotNull("No value for context name", value);
- assertEquals("Incorrect value for context name", "WebApp", value);
+ assertNotNull(value, "No value for context name");
+ assertEquals("WebApp", value, "Incorrect value for context name");
} catch (final IllegalStateException e) {
fail("Failed to initialize Log4j properly." + e.getMessage());
}
@@ -90,10 +90,10 @@
initializer.start();
initializer.setLoggerContext();
final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
- assertNotNull("No LoggerContext", ctx);
- assertNotNull("No ServletContext", WebLoggerContextUtils.getServletContext());
+ assertNotNull(ctx, "No LoggerContext");
+ assertNotNull(WebLoggerContextUtils.getServletContext(), "No ServletContext");
final Configuration config = ctx.getConfiguration();
- assertNotNull("No Configuration", config);
+ assertNotNull(config, "No Configuration");
final Map<String, Appender> appenders = config.getAppenders();
for (final Map.Entry<String, Appender> entry : appenders.entrySet()) {
if (entry.getKey().equals("file")) {
@@ -103,8 +103,8 @@
}
final StrSubstitutor substitutor = config.getStrSubstitutor();
String value = substitutor.replace("${web:contextPathName:-default}");
- assertNotNull("No value for context name", value);
- assertEquals("Incorrect value for context name", "default", value);
+ assertEquals("default", value, "Incorrect value for context name");
+ assertNotNull(value, "No value for context name");
initializer.stop();
ContextAnchor.THREAD_CONTEXT.remove();
}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 06f9c96..9ca3f47 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -31,10 +31,20 @@
- "remove" - Removed
-->
<release version="3.0.0" date="2021-MM-DD" description="GA Release 3.0.0">
- <action issue="LOG4J2-2977" dev="rgrabowski" type="fix">
+ <action issue="LOG4J2-2624" dev="mattsicker" type="fix" due-to="Tim Perry">
+ Allow auto-shutdown of log4j in log4j-web to be turned off and provide a
+ ServletContextListener "Log4jShutdownOnContextDestroyedListener" to stop log4j.
+ Register the listener at the top of web.xml to ensure the shutdown happens last.
+ </action>
+ <action issue="LOG4J2-1606" dev="mattsicker" type="fix" due-to="Tim Perry">
+ Allow auto-shutdown of log4j in log4j-web to be turned off and provide a
+ ServletContextListener "Log4jShutdownOnContextDestroyedListener" to stop log4j.
+ Register the listener at the top of web.xml to ensure the shutdown happens last.
+ </action>
+ <action issue="LOG4J2-2977" dev="vy" due-to="Ron Grabowski">
Replace outdated PatternLayout.createLayout() calls in docs with createDefaultLayout().
</action>
- <action issue="LOG4J2-2973" dev="fricchiuti" type="fix">
+ <action issue="LOG4J2-2973" dev="vy" type="fix" due-to="Fabio Ricchiuti">
Rename EventTemplateAdditionalField#type (conflicting with properties file parser) to "format".
</action>
<action issue="LOG4J2-2999" dev="vy" type="add">