Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.13.0
-
None
-
None
-
The problem depends on the implemention of the WeakReference-check in the used garbage collection algorithm of the JVM.
Examples of affected JVMs:
- OpenJ9 OpenJDK8U-jdk_x64_linux_openj9_8u232b09_openj9-0.17.0.tar.gz (in combination with log4j-core-2.13.0.jar)
- IBM JRE 1.8.0_221 z/OS (with log4j-2.8.1)
- OpenJ9 JDK8 linux_x86 2115.LT2 (with log4j-2.3)
- OpenJ9 JDK11 x86_mac 441.WL4 (with log4j-2.3)
- OpenJ9 JDK13 146 (https://ci.eclipse.org/openj9/job/Test_openjdk13_j9_extended.system_ppc64le_linux_Nightly/146/ with log4j-2.3)
The problem depends on the implemention of the WeakReference-check in the used garbage collection algorithm of the JVM. Examples of affected JVMs: OpenJ9 OpenJDK8U-jdk_x64_linux_openj9_8u232b09_openj9-0.17.0.tar.gz (in combination with log4j-core-2.13.0.jar) IBM JRE 1.8.0_221 z/OS (with log4j-2.8.1) OpenJ9 JDK8 linux_x86 2115.LT2 (with log4j-2.3) OpenJ9 JDK11 x86_mac 441.WL4 (with log4j-2.3) OpenJ9 JDK13 146 ( https://ci.eclipse.org/openj9/job/Test_openjdk13_j9_extended.system_ppc64le_linux_Nightly/146/ with log4j-2.3)
Description
A race-condition between GC and WeakReference in ClassLoaderContextSelector can lead to a NPE in Log4jContextFactory.
Exception in thread "main" java.lang.NullPointerException
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:602)
In org.apache.logging.log4j.core.selector.ClassLoaderContextSelector there is the following creation of a LoggerContext in method locateContext:
LoggerContext ctx = createContext(name, configLocation); final AtomicReference<WeakReference<LoggerContext>> r = new AtomicReference<>(); r.set(new WeakReference<>(ctx)); CONTEXT_MAP.putIfAbsent(name, r); ctx = CONTEXT_MAP.get(name).get().get(); return ctx;
The created LoggerContext is stored in local variable ctx. After storing the LoggerContext into a WeakReference the local variable isn't read until overridden by a new value out of the CONTEXT_MAP. A garbage collection between creating the WeakReference and reading the CONTEXT_MAP might remove the LoggerContext.
This leads to intermittent failures in JVMs like OpenJ9 which mark locals as not-an-object so they can be collected as soon as possible. See also: https://github.com/eclipse/openj9/issues/4005
Attachments
Issue Links
- relates to
-
LOG4J2-477 NPE in ClassLoaderContextSelector
- Closed