[
https://issues.apache.org/jira/browse/LOG4J2-2756?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17011602#comment-17011602
]
Sascha Rogmann commented on LOG4J2-2756:
----------------------------------------
The following proposal holds the LoggerContext until the CONTEXT_MAP has been
read.
{code:java} final LoggerContext ctxJustCreated = createContext(name,
configLocation);
final AtomicReference<WeakReference<LoggerContext>> r = new
AtomicReference<>();
r.set(new WeakReference<>(ctxJustCreated));
// CONTEXT_MAP: use only one LoggerContext in case of parallel
threads.
CONTEXT_MAP.putIfAbsent(name, r);
final LoggerContext ctxContextMap =
CONTEXT_MAP.get(name).get().get();
// LOG4J2-2756: Prevent the GC from collection of ctxJustCreated by
reading it
// after the call of CONTEXT_MAP.get.
if (ctxContextMap == null) {
// The call of ctxJustCreated.toString() turns ctxJustCreated
into
// a strong reference and prevents ctxContextMap == null.
throw new IllegalStateException(String.format(
"CONTEXT_MAP contains neither just created
LoggerContext (%s) nor a parallel computed one.",
ctxJustCreated));
}
return ctxContextMap;
{code}
> 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
> Priority: Major
>
> 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)