Description
Description
LoggerContext / LoggerRegistry don't play well together in using weak references, which can result in a null
logger if the GC kicks in at a bad timing.
Configuration
Version: 2.24.1
Operating system: Linux / macOS
JDK: 21.0.4
Logs
java.lang.NullPointerException
Cannot invoke "org.apache.logging.log4j.spi.ExtendedLogger.logIfEnabled(String, org.apache.logging.log4j.Level, org.apache.logging.log4j.Marker, String)" because "this.logger" is null
at org.apache.logging.slf4j.Log4jLogger.warn(Log4jLogger.java:233)
at <internal company code>
Reproduction
LoggerContext
keeps a local reference tonewLogger
, but this isn't safe to keep a reference (see below).LoggerRegistry.putIfAbsent
takes the instance and creates aWeakReference
from it.- Unfortunate GC timing might result in the weak reference being cleared and the following
getLogger
call returningnull
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
https://docs.oracle.com/javase/specs/jls/se21/html/jls-12.html#jls-12.6.1
Fix
#2936 should fix this, but is currently unreleased.
Reference.reachabilityFence
would also fix this, but is JDK 9+ only.
See also: https://shipilev.net/jvm/anatomy-quarks/8-local-var-reachability/