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;