This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/master by this push:
     new eb0090b45e Uniformise context selector logic
eb0090b45e is described below

commit eb0090b45eb1fff9fbf1279a26c8052e55bdfefe
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Sun Jul 17 10:12:42 2022 +0200

    Uniformise context selector logic
    
    The `ClassloaderContextSelector` passes the `LateConfigTest`, whereas
    the `BasicContextSelector` does not. Also the `BasicContextSelector`
    returns the current context even if `currentContext == false`.
---
 .../apache/logging/log4j/core/LateConfigTest.java  | 52 +++++++++-------
 .../log4j/core/impl/Log4jContextFactoryTest.java   |  8 ++-
 .../async/BasicAsyncLoggerContextSelector.java     | 63 ++++---------------
 .../log4j/core/selector/BasicContextSelector.java  | 72 ++++++++++++++++------
 .../log4j/core/selector/ContextSelector.java       |  4 +-
 5 files changed, 103 insertions(+), 96 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LateConfigTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LateConfigTest.java
index 94392322df..f51f411bd5 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LateConfigTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LateConfigTest.java
@@ -16,49 +16,59 @@
  */
 package org.apache.logging.log4j.core;
 
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.io.File;
+import java.util.stream.Stream;
 
+import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
+import org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector;
 import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.Configurator;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
 import org.apache.logging.log4j.core.config.xml.XmlConfiguration;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeAll;
+import org.apache.logging.log4j.core.impl.Log4jContextFactory;
+import org.apache.logging.log4j.core.selector.BasicContextSelector;
+import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;
+import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.plugins.di.DI;
+import org.apache.logging.log4j.plugins.di.Injector;
 import org.junit.jupiter.api.Tag;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 
 @Tag("functional")
 public class LateConfigTest {
 
     private static final String CONFIG = "target/test-classes/log4j-test1.xml";
-    private static LoggerContext context;
-
-    @BeforeAll
-    public static void setupClass() {
-        context = LoggerContext.getContext(false);
-    }
+    // This class will be the caller of `Log4jContextFactory`
+    private static final String FQCN = Log4jContextFactory.class.getName();
 
-    @AfterAll
-    public static void tearDownClass() {
-        Configurator.shutdown(context);
-        StatusLogger.getLogger().reset();
+    static Stream<Log4jContextFactory> selectors() {
+        Injector injector = DI.createInjector();
+        injector.init();
+        return Stream
+                .<ContextSelector>of(new 
ClassLoaderContextSelector(injector.copy()), new 
BasicContextSelector(injector.copy()),
+                        new AsyncLoggerContextSelector(injector.copy()), new 
BasicAsyncLoggerContextSelector(injector.copy()))
+                .map(Log4jContextFactory::new);
     }
 
-    @Test
-    public void testReconfiguration() throws Exception {
+    @ParameterizedTest
+    @MethodSource("selectors")
+    public void testReconfiguration(final Log4jContextFactory factory) throws 
Exception {
+        LoggerContext context = factory.getContext(FQCN, null, null, false);
         final Configuration cfg = context.getConfiguration();
         assertNotNull(cfg, "No configuration");
         assertTrue(cfg instanceof DefaultConfiguration, "Not set to default 
configuration");
         final File file = new File(CONFIG);
-        final LoggerContext loggerContext = LoggerContext.getContext(null, 
false, file.toURI());
+        final LoggerContext loggerContext = factory.getContext(FQCN, null, 
null, false, file.toURI(), null);
         assertNotNull(loggerContext, "No Logger Context");
         final Configuration newConfig = loggerContext.getConfiguration();
         assertNotSame(cfg, newConfig, "Configuration not reset");
         assertTrue(newConfig instanceof XmlConfiguration, "Reconfiguration 
failed");
-        context = LoggerContext.getContext(false);
+        context = factory.getContext(FQCN, null, null, false);
         final Configuration sameConfig = context.getConfiguration();
         assertSame(newConfig, sameConfig, "Configuration should not have been 
reset");
     }
diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/Log4jContextFactoryTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/Log4jContextFactoryTest.java
index 74b2a5522a..2d64c58e85 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/Log4jContextFactoryTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/Log4jContextFactoryTest.java
@@ -19,6 +19,8 @@ package org.apache.logging.log4j.core.impl;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.apache.logging.log4j.core.selector.BasicContextSelector;
+import org.apache.logging.log4j.plugins.di.DI;
+import org.apache.logging.log4j.plugins.di.Injector;
 import org.junit.jupiter.api.Test;
 
 public class Log4jContextFactoryTest {
@@ -29,11 +31,13 @@ public class Log4jContextFactoryTest {
      */
     @Test
     public void testParameterPriority() {
-        Log4jContextFactory factory = new Log4jContextFactory(new 
BasicContextSelector());
+        final Injector injector = DI.createInjector();
+        injector.init();
+        Log4jContextFactory factory = new Log4jContextFactory(new 
BasicContextSelector(injector));
         assertEquals(BasicContextSelector.class, 
factory.getSelector().getClass());
         factory = new Log4jContextFactory(factory);
         assertEquals(Log4jContextFactory.class, 
factory.getShutdownCallbackRegistry().getClass());
-        factory = new Log4jContextFactory(new BasicContextSelector(), factory);
+        factory = new Log4jContextFactory(new BasicContextSelector(injector), 
factory);
         assertEquals(BasicContextSelector.class, 
factory.getSelector().getClass());
         assertEquals(Log4jContextFactory.class, 
factory.getShutdownCallbackRegistry().getClass());
     }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
index cec0a2c81c..9658f0302f 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector.java
@@ -16,15 +16,13 @@
  */
 package org.apache.logging.log4j.core.async;
 
+import java.net.URI;
+
 import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.impl.ContextAnchor;
-import org.apache.logging.log4j.core.selector.ContextSelector;
+import org.apache.logging.log4j.core.selector.BasicContextSelector;
+import org.apache.logging.log4j.plugins.Inject;
 import org.apache.logging.log4j.plugins.Singleton;
-
-import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
+import org.apache.logging.log4j.plugins.di.Injector;
 
 /**
  * Returns either this Thread's context or the default {@link 
AsyncLoggerContext}.
@@ -32,54 +30,15 @@ import java.util.concurrent.TimeUnit;
  * due to the reduced overhead avoiding classloader lookups.
  */
 @Singleton
-public class BasicAsyncLoggerContextSelector implements ContextSelector {
-
-    private static final AsyncLoggerContext CONTEXT = new 
AsyncLoggerContext("AsyncDefault");
-
-    @Override
-    public void shutdown(final String fqcn, final ClassLoader loader, final 
boolean currentContext, final boolean allContexts) {
-        final LoggerContext ctx = getContext(fqcn, loader, currentContext);
-        if (ctx != null && ctx.isStarted()) {
-            ctx.stop(DEFAULT_STOP_TIMEOUT, TimeUnit.MILLISECONDS);
-        }
-    }
+public class BasicAsyncLoggerContextSelector extends BasicContextSelector {
 
-    @Override
-    public boolean hasContext(final String fqcn, final ClassLoader loader, 
final boolean currentContext) {
-        final LoggerContext ctx = getContext(fqcn, loader, currentContext);
-        return ctx != null && ctx.isStarted();
+    @Inject
+    public BasicAsyncLoggerContextSelector(Injector injector) {
+        super(injector);
     }
 
     @Override
-    public LoggerContext getContext(final String fqcn, final ClassLoader 
loader, final boolean currentContext) {
-        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
-        return ctx != null ? ctx : CONTEXT;
+    protected LoggerContext createContext() {
+        return new AsyncLoggerContext("AsyncDefault", null, (URI) null, 
injector);
     }
-
-
-    @Override
-    public LoggerContext getContext(
-            final String fqcn,
-            final ClassLoader loader,
-            final boolean currentContext,
-            final URI configLocation) {
-        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
-        return ctx != null ? ctx : CONTEXT;
-    }
-
-    @Override
-    public void removeContext(final LoggerContext context) {
-        // does not remove anything
-    }
-
-    @Override
-    public boolean isClassLoaderDependent() {
-        return false;
-    }
-
-    @Override
-    public List<LoggerContext> getLoggerContexts() {
-        return Collections.singletonList(CONTEXT);
-    }
-
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java
index bee6b4cd8f..77fbfb173a 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/BasicContextSelector.java
@@ -16,21 +16,35 @@
  */
 package org.apache.logging.log4j.core.selector;
 
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.impl.ContextAnchor;
-import org.apache.logging.log4j.plugins.Singleton;
-
 import java.net.URI;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.impl.ContextAnchor;
+import org.apache.logging.log4j.plugins.Inject;
+import org.apache.logging.log4j.plugins.Singleton;
+import org.apache.logging.log4j.plugins.di.Injector;
+import org.apache.logging.log4j.spi.LoggerContextShutdownAware;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.LazyValue;
+
 /**
  * Returns either this Thread's context or the default LoggerContext.
  */
 @Singleton
-public class BasicContextSelector implements ContextSelector {
+public class BasicContextSelector implements ContextSelector, 
LoggerContextShutdownAware {
+
+    private static final Logger LOGGER = StatusLogger.getLogger();
 
-    private static final LoggerContext CONTEXT = new LoggerContext("Default");
+    protected final LazyValue<LoggerContext> context = 
LazyValue.from(this::createContext);
+    protected final Injector injector;
+
+    @Inject
+    public BasicContextSelector(final Injector injector) {
+        this.injector = injector;
+    }
 
     @Override
     public void shutdown(final String fqcn, final ClassLoader loader, final 
boolean currentContext, final boolean allContexts) {
@@ -40,6 +54,13 @@ public class BasicContextSelector implements ContextSelector 
{
         }
     }
 
+    @Override
+    public void contextShutdown(org.apache.logging.log4j.spi.LoggerContext 
loggerContext) {
+        if (loggerContext instanceof LoggerContext) {
+            removeContext((LoggerContext) loggerContext);
+        }
+    }
+
     @Override
     public boolean hasContext(final String fqcn, final ClassLoader loader, 
final boolean currentContext) {
         final LoggerContext ctx = getContext(fqcn, loader, currentContext);
@@ -48,26 +69,36 @@ public class BasicContextSelector implements 
ContextSelector {
 
     @Override
     public LoggerContext getContext(final String fqcn, final ClassLoader 
loader, final boolean currentContext) {
-        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
-        return ctx != null ? ctx : CONTEXT;
+        return getContext(fqcn, loader, currentContext, null);
     }
 
-
     @Override
     public LoggerContext getContext(final String fqcn, final ClassLoader 
loader, final boolean currentContext,
-                                    final URI configLocation) {
-
-        final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
-        return ctx != null ? ctx : CONTEXT;
-    }
-
-    public LoggerContext locateContext(final String name, final String 
configLocation) {
-        return CONTEXT;
+            final URI configLocation) {
+        if (currentContext) {
+            final LoggerContext ctx = ContextAnchor.THREAD_CONTEXT.get();
+            if (ctx != null) {
+                return ctx;
+            }
+        }
+        final LoggerContext ctx = context.get();
+        if (configLocation != null) {
+            if (ctx.getConfigLocation() == null) {
+                LOGGER.debug("Setting configuration to {}", configLocation);
+                ctx.setConfigLocation(configLocation);
+            } else if (!ctx.getConfigLocation().equals(configLocation)) {
+                LOGGER.warn("getContext called with URI {}. Existing 
LoggerContext has URI {}", configLocation,
+                        ctx.getConfigLocation());
+            }
+        }
+        return ctx;
     }
 
     @Override
     public void removeContext(final LoggerContext context) {
-        // does not remove anything
+        if (context == this.context.get()) {
+            this.context.set(null);
+        }
     }
 
     @Override
@@ -77,7 +108,10 @@ public class BasicContextSelector implements 
ContextSelector {
 
     @Override
     public List<LoggerContext> getLoggerContexts() {
-        return List.of(CONTEXT);
+        return List.of(context.get());
     }
 
+    protected LoggerContext createContext() {
+        return new LoggerContext("Default", null, (URI) null, injector);
+    }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
index 85fd2de0d6..e98323a1aa 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/selector/ContextSelector.java
@@ -82,7 +82,7 @@ public interface ContextSelector {
      */
     default LoggerContext getContext(final String fqcn, final ClassLoader 
loader, final Map.Entry<String, Object> entry, final boolean currentContext) {
         final LoggerContext lc = getContext(fqcn, loader, currentContext);
-        if (lc != null) {
+        if (entry != null) {
             lc.putObject(entry.getKey(), entry.getValue());
         }
         return lc;
@@ -112,7 +112,7 @@ public interface ContextSelector {
     default LoggerContext getContext(final String fqcn, final ClassLoader 
loader, final Map.Entry<String, Object> entry,
             final boolean currentContext, final URI configLocation) {
         final LoggerContext lc = getContext(fqcn, loader, currentContext, 
configLocation);
-        if (lc != null) {
+        if (entry != null) {
             lc.putObject(entry.getKey(), entry.getValue());
         }
         return lc;

Reply via email to