You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@logging.apache.org by "Sascha Rogmann (Jira)" <ji...@apache.org> on 2020/01/08 10:24:00 UTC

[jira] [Created] (LOG4J2-2756) ClassLoaderContextSelector: WeakReference and GC

Sascha Rogmann created LOG4J2-2756:
--------------------------------------

             Summary: ClassLoaderContextSelector: WeakReference and GC
                 Key: LOG4J2-2756
                 URL: https://issues.apache.org/jira/browse/LOG4J2-2756
             Project: Log4j 2
          Issue Type: Bug
          Components: Core
    Affects Versions: 2.13.0
         Environment: 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)
            Reporter: Sascha Rogmann


A race-condition between GC and WeakReference in ClassLoaderContextSelector can lead to a NPE in Log4jContextFactory.
{code:java}
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)
{code}
In org.apache.logging.log4j.core.selector.ClassLoaderContextSelector there is the following creation of a LoggerContext in method locateContext:
{code:java}
            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;
{code}
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]



--
This message was sent by Atlassian Jira
(v8.3.4#803005)