Skip to content

Commit 4e107c0

Browse files
committed
Fix NPE caused by MDCContextMap
1 parent 95a90e0 commit 4e107c0

File tree

5 files changed

+96
-3
lines changed

5 files changed

+96
-3
lines changed

log4j-to-slf4j/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@
103103
<artifactId>log4j-api-test</artifactId>
104104
<scope>test</scope>
105105
</dependency>
106+
<dependency>
107+
<groupId>org.mockito</groupId>
108+
<artifactId>mockito-core</artifactId>
109+
<scope>test</scope>
110+
</dependency>
106111
</dependencies>
107112

108113
<build>

log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/MDCContextMap.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.logging.slf4j;
1818

19+
import java.util.HashMap;
1920
import java.util.Map;
2021
import java.util.Map.Entry;
2122
import org.apache.logging.log4j.spi.CleanableThreadContextMap;
@@ -75,13 +76,12 @@ public boolean containsKey(final String key) {
7576
}
7677

7778
@Override
78-
@SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API
7979
public Map<String, String> getCopy() {
80-
return MDC.getCopyOfContextMap();
80+
final Map<String, String> contextMap = MDC.getCopyOfContextMap();
81+
return contextMap != null ? contextMap : new HashMap<>();
8182
}
8283

8384
@Override
84-
@SuppressWarnings("unchecked") // nothing we can do about this, restricted by SLF4J API
8585
public Map<String, String> getImmutableMapOrNull() {
8686
return MDC.getCopyOfContextMap();
8787
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.logging.slf4j;
18+
19+
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.mockito.Mockito.mock;
21+
import static org.mockito.Mockito.times;
22+
import static org.mockito.Mockito.verify;
23+
import static org.mockito.Mockito.verifyNoMoreInteractions;
24+
import static org.mockito.Mockito.when;
25+
26+
import org.apache.logging.log4j.spi.ThreadContextMap;
27+
import org.junit.jupiter.api.Test;
28+
import org.junitpioneer.jupiter.Issue;
29+
import org.slf4j.MDCTestHelper;
30+
import org.slf4j.spi.MDCAdapter;
31+
32+
class MDCContextMapTest {
33+
34+
@Test
35+
@Issue("https://github.com/apache/logging-log4j2/issues/1426")
36+
void nonNullGetCopy() {
37+
final ThreadContextMap contextMap = new MDCContextMap();
38+
final MDCAdapter mockAdapter = mock(MDCAdapter.class);
39+
when(mockAdapter.getCopyOfContextMap()).thenReturn(null);
40+
final MDCAdapter adapter = MDCTestHelper.replaceMDCAdapter(mockAdapter);
41+
try {
42+
assertThat(contextMap.getImmutableMapOrNull()).isNull();
43+
assertThat(contextMap.getCopy()).isNotNull();
44+
verify(mockAdapter, times(2)).getCopyOfContextMap();
45+
verifyNoMoreInteractions(mockAdapter);
46+
} finally {
47+
MDCTestHelper.replaceMDCAdapter(adapter);
48+
}
49+
}
50+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.slf4j;
18+
19+
import org.slf4j.spi.MDCAdapter;
20+
21+
public class MDCTestHelper {
22+
23+
public static MDCAdapter replaceMDCAdapter(final MDCAdapter adapter) {
24+
final MDCAdapter old = MDC.mdcAdapter;
25+
MDC.mdcAdapter = adapter;
26+
return old;
27+
}
28+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xmlns="http://logging.apache.org/log4j/changelog"
4+
xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.2.xsd"
5+
type="fixed">
6+
<issue id="1426" link="https://github.com/apache/logging-log4j2/pull/1426"/>
7+
<description format="asciidoc">
8+
Fix NPE in `CloseableThreadContext`.
9+
</description>
10+
</entry>

0 commit comments

Comments
 (0)