in log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.java [179:251]
private LoggerContext locateContext(final ClassLoader loaderOrNull, final Map.Entry<String, Object> entry,
final URI configLocation) {
// LOG4J2-477: class loader may be null
final ClassLoader loader = loaderOrNull != null ? loaderOrNull : ClassLoader.getSystemClassLoader();
final String name = toContextMapKey(loader);
AtomicReference<WeakReference<LoggerContext>> ref = CONTEXT_MAP.get(name);
if (ref == null) {
if (configLocation == null) {
ClassLoader parent = loader.getParent();
while (parent != null) {
ref = CONTEXT_MAP.get(toContextMapKey(parent));
if (ref != null) {
final WeakReference<LoggerContext> r = ref.get();
final LoggerContext ctx = r.get();
if (ctx != null) {
return ctx;
}
}
parent = parent.getParent();
/* In Tomcat 6 the parent of the JSP classloader is the webapp classloader which would be
configured by the WebAppContextListener. The WebAppClassLoader is also the ThreadContextClassLoader.
In JBoss 5 the parent of the JSP ClassLoader is the WebAppClassLoader which is also the
ThreadContextClassLoader. However, the parent of the WebAppClassLoader is the ClassLoader
that is configured by the WebAppContextListener.
ClassLoader threadLoader = null;
try {
threadLoader = Thread.currentThread().getContextClassLoader();
} catch (Exception ex) {
// Ignore SecurityException
}
if (threadLoader != null && threadLoader == parent) {
break;
} else {
parent = parent.getParent();
} */
}
}
final LoggerContext ctx = createContext(name, configLocation);
if (entry != null) {
ctx.putObject(entry.getKey(), entry.getValue());
}
final LoggerContext newContext = CONTEXT_MAP.computeIfAbsent(name,
k -> new AtomicReference<>(new WeakReference<>(ctx))).get().get();
if (newContext == ctx) {
ctx.addShutdownListener(this);
}
return newContext;
}
final WeakReference<LoggerContext> weakRef = ref.get();
LoggerContext ctx = weakRef.get();
if (ctx != null) {
if (entry != null && ctx.getObject(entry.getKey()) == null) {
ctx.putObject(entry.getKey(), entry.getValue());
}
if (ctx.getConfigLocation() == null && configLocation != null) {
LOGGER.debug("Setting configuration to {}", configLocation);
ctx.setConfigLocation(configLocation);
} else if (ctx.getConfigLocation() != null && configLocation != null
&& !ctx.getConfigLocation().equals(configLocation)) {
LOGGER.warn("locateContext called with URI {}. Existing LoggerContext has URI {}", configLocation,
ctx.getConfigLocation());
}
return ctx;
}
ctx = createContext(name, configLocation);
if (entry != null) {
ctx.putObject(entry.getKey(), entry.getValue());
}
ref.compareAndSet(weakRef, new WeakReference<>(ctx));
return ctx;
}