This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch fix/apply-property-environment in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 54f8cb4233c7d3e4ea748643232d9dbe068a5563 Author: Piotr P. Karwasz <[email protected]> AuthorDate: Fri Mar 15 12:32:22 2024 +0100 Adapt `log4j-core` to Log4j API 2.x --- .../org/apache/logging/log4j/util/NameUtil.java | 76 ------------- .../log4j/core/test/BasicConfigurationFactory.java | 4 +- .../logging/log4j/core/test/TestConstants.java | 26 ++--- .../test/junit/AbstractExternalFileCleaner.java | 2 +- .../logging/log4j/core}/test/junit/CleanFiles.java | 2 +- .../log4j/core}/test/junit/CleanFolders.java | 2 +- .../log4j/core/test/junit/LoggerContextRule.java | 2 - .../log4j/core/test/layout/Log4j2_1482_Test.java | 2 +- .../org/apache/logging/log4j/core/LoggerTest.java | 9 +- .../RollingAppenderDirectWriteStartupSizeTest.java | 2 +- .../RollingFileAppenderInterruptedThreadTest.java | 2 +- .../async/AsyncQueueFullPolicyFactoryTest.java | 1 - .../log4j/core/config/TestConfiguratorError.java | 3 - .../core/impl/ThreadContextDataInjectorTest.java | 3 +- .../selector/ClassLoaderContextSelectorTest.java | 2 +- .../log4j/core/tools/GenerateCustomLoggerTest.java | 4 +- .../core/tools/GenerateExtendedLoggerTest.java | 4 +- .../logging/log4j/core/util/JsonUtilsTest.java | 68 ------------ .../apache/logging/log4j/core/LoggerContext.java | 17 +-- .../core/appender/MemoryMappedFileManager.java | 2 +- .../log4j/core/config/AbstractConfiguration.java | 28 +++-- .../core/config/DefaultConfigurationFactory.java | 6 +- .../log4j/core/config/NullConfiguration.java | 4 +- .../config/builder/impl/BuiltConfiguration.java | 4 +- .../log4j/core/config/json/JsonConfiguration.java | 2 +- .../core/filter/MutableThreadContextMapFilter.java | 2 +- .../logging/log4j/core/impl/DefaultBundle.java | 38 +++++-- .../log4j/core/impl/Log4jContextFactory.java | 13 +-- .../logging/log4j/core/impl/Log4jProvider.java | 2 +- .../logging/log4j/core/impl/PropertyKeys.java | 2 + .../log4j/core/impl/ThreadContextDataInjector.java | 12 ++- .../apache/logging/log4j/core/util/JsonUtils.java | 117 --------------------- .../org/apache/logging/log4j/core/util/Loader.java | 4 +- .../logging/log4j/core/util/WatchManager.java | 9 +- .../apache/logging/log4j/kit/json}/JsonReader.java | 2 +- .../logging/log4j/kit/json/package-info.java | 22 ++++ .../kit/recycler/RecyclerFactoryProvider.java | 5 + .../{PropertyKeys.java => RecyclerKeys.java} | 2 +- .../internal/DummyRecyclerFactoryProvider.java | 2 + .../ThreadLocalRecyclerFactoryProvider.java | 4 +- .../logging/log4j/kit/json}/JsonReaderTest.java | 3 +- 41 files changed, 161 insertions(+), 355 deletions(-) diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/NameUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/NameUtil.java deleted file mode 100644 index dd1cdac713..0000000000 --- a/log4j-api/src/main/java/org/apache/logging/log4j/util/NameUtil.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.logging.log4j.util; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Objects; - -/** - * - */ -@InternalApi -public final class NameUtil { - - private NameUtil() {} - - public static String getSubName(final String name) { - if (Strings.isEmpty(name)) { - return null; - } - final int i = name.lastIndexOf('.'); - return i > 0 ? name.substring(0, i) : Strings.EMPTY; - } - - /** - * Calculates the <a href="https://en.wikipedia.org/wiki/MD5">MD5</a> hash - * of the given input string encoded using the default platform - * {@link Charset charset}. - * <p> - * <b>MD5 has severe vulnerabilities and should not be used for sharing any - * sensitive information.</b> This function should only be used to create - * unique identifiers, e.g., configuration element names. - * - * @param input string to be hashed - * @return string composed of 32 hexadecimal digits of the calculated hash - */ - @SuppressFBWarnings(value = "WEAK_MESSAGE_DIGEST_MD5", justification = "Used to create unique identifiers.") - @Deprecated - public static String md5(final String input) { - Objects.requireNonNull(input, "input"); - try { - final byte[] inputBytes = input.getBytes(); - final MessageDigest digest = MessageDigest.getInstance("MD5"); - final byte[] bytes = digest.digest(inputBytes); - final StringBuilder md5 = new StringBuilder(bytes.length * 2); - for (final byte b : bytes) { - md5.append(Character.forDigit((0xFF & b) >> 4, 16)); - md5.append(Character.forDigit(0x0F & b, 16)); - } - return md5.toString(); - } - // Every implementation of the Java platform is required to support MD5. - // Hence, this catch block should be unreachable. - // See https://docs.oracle.com/javase/8/docs/api/java/security/MessageDigest.html - // for details. - catch (final NoSuchAlgorithmException error) { - throw new RuntimeException(error); - } - } -} diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/BasicConfigurationFactory.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/BasicConfigurationFactory.java index 643b77741d..8e4f54b948 100644 --- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/BasicConfigurationFactory.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/BasicConfigurationFactory.java @@ -24,9 +24,9 @@ import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.ConfigurationFactory; import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.kit.env.PropertyEnvironment; import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory; import org.apache.logging.log4j.plugins.di.DI; -import org.apache.logging.log4j.util.PropertiesUtil; /** * @@ -61,7 +61,7 @@ public class BasicConfigurationFactory extends ConfigurationFactory { super( loggerContext, ConfigurationSource.NULL_SOURCE, - loggerContext != null ? loggerContext.getEnvironment() : PropertiesUtil.getProperties(), + loggerContext != null ? loggerContext.getEnvironment() : PropertyEnvironment.getGlobal(), loggerContext != null ? (ConfigurableInstanceFactory) loggerContext.getInstanceFactory() : DI.createInitializedFactory()); diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java index 0179a9300c..3661ed3ec1 100644 --- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java @@ -23,21 +23,21 @@ public final class TestConstants { private TestConstants() {} - private static final String ASYNC = "Async."; + private static final String ASYNC = "log4j.Async."; public static final String ASYNC_FORMAT_MESSAGES_IN_BACKGROUND = ASYNC + "formatMessagesInBackground"; - private static final String ASYNC_LOGGER = "AsyncLogger."; + private static final String ASYNC_LOGGER = "log4j.AsyncLogger."; public static final String ASYNC_LOGGER_EXCEPTION_HANDLER = ASYNC_LOGGER + "exceptionHandler"; public static final String ASYNC_LOGGER_RING_BUFFER_SIZE = ASYNC_LOGGER + "ringBufferSize"; - private static final String ASYNC_LOGGER_CONFIG = "AsyncLoggerConfig."; + private static final String ASYNC_LOGGER_CONFIG = "log4j.AsyncLoggerConfig."; public static final String ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE = ASYNC_LOGGER_CONFIG + "ringBufferSize"; - private static final String CONFIGURATION = "Configuration."; + private static final String CONFIGURATION = "log4j.Configuration."; /** * @see PropertyKeys.Configuration */ @@ -49,27 +49,29 @@ public final class TestConstants { public static final String CONFIGURATION_USE_PRECISE_CLOCK = CONFIGURATION + "usePreciseClock"; - public static final String CONSOLE_JANSI_ENABLED = "Console.jansiEnabled"; + public static final String CONSOLE_JANSI_ENABLED = "log4j.Console.jansiEnabled"; - private static final String GC = "GC."; + private static final String GC = "log4j.GC."; public static final String GC_ENABLE_DIRECT_ENCODERS = GC + "enableDirectEncoders"; - private static final String LOGGER_CONTEXT = "LoggerContext."; + private static final String LOGGER_CONTEXT = "log4j.LoggerContext."; + + public static final String LOGGER_CONTEXT_FACTORY = LOGGER_CONTEXT + "factory"; public static final String LOGGER_CONTEXT_LOG_EVENT_FACTORY = LOGGER_CONTEXT + "logEventFactory"; public static final String LOGGER_CONTEXT_SELECTOR = LOGGER_CONTEXT + "selector"; - private static final String MESSAGE = "Message."; + private static final String MESSAGE = "log4j.Message."; public static final String MESSAGE_FACTORY = MESSAGE + "factory"; - public static final String VERSION1_CONFIGURATION = "Version1.configuration"; + public static final String VERSION1_CONFIGURATION = "log4j.Version1.configuration"; - public static final String VERSION1_COMPATIBILITY = "Version1.compatibility"; + public static final String VERSION1_COMPATIBILITY = "log4j.Version1.compatibility"; - private static final String THREAD_CONTEXT = "ThreadContext."; + private static final String THREAD_CONTEXT = "log4j.ThreadContext."; public static final String THREAD_CONTEXT_CONTEXT_DATA = THREAD_CONTEXT + "contextData"; @@ -77,7 +79,7 @@ public final class TestConstants { public static final String THREAD_CONTEXT_MAP_CLASS = THREAD_CONTEXT + "mapClass"; - private static final String WEB = "WEB."; + private static final String WEB = "log4j.WEB."; public static final String WEB_IS_WEB_APP = WEB + "isWebApp"; diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/AbstractExternalFileCleaner.java similarity index 99% rename from log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java rename to log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/AbstractExternalFileCleaner.java index 79c8c95716..afac8b941b 100644 --- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/AbstractExternalFileCleaner.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/AbstractExternalFileCleaner.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.logging.log4j.test.junit; +package org.apache.logging.log4j.core.test.junit; import java.io.File; import java.io.IOException; diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFiles.java similarity index 97% rename from log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java rename to log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFiles.java index 67904e36c2..1a263e12a9 100644 --- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFiles.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFiles.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.logging.log4j.test.junit; +package org.apache.logging.log4j.core.test.junit; import java.io.File; import java.io.IOException; diff --git a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFolders.java similarity index 98% rename from log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java rename to log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFolders.java index c414c7eaec..40cb9c61ac 100644 --- a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/CleanFolders.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/CleanFolders.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.logging.log4j.test.junit; +package org.apache.logging.log4j.core.test.junit; import java.io.File; import java.io.IOException; diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java index 58c40c0f05..910dbacd40 100644 --- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java @@ -35,8 +35,6 @@ import org.apache.logging.log4j.core.util.NetUtils; import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory; import org.apache.logging.log4j.plugins.di.DI; import org.apache.logging.log4j.status.StatusLogger; -import org.apache.logging.log4j.test.junit.CleanFiles; -import org.apache.logging.log4j.test.junit.CleanFolders; import org.apache.logging.log4j.util.Strings; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/layout/Log4j2_1482_Test.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/layout/Log4j2_1482_Test.java index 084a2b3786..79f8bbd17f 100644 --- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/layout/Log4j2_1482_Test.java +++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/layout/Log4j2_1482_Test.java @@ -27,7 +27,7 @@ import java.util.List; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.test.categories.Layouts; -import org.apache.logging.log4j.test.junit.CleanFolders; +import org.apache.logging.log4j.core.test.junit.CleanFolders; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java index 49f3058956..4b5c9066ef 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/LoggerTest.java @@ -51,7 +51,6 @@ import org.apache.logging.log4j.message.ReusableMessageFactory; import org.apache.logging.log4j.message.SimpleMessage; import org.apache.logging.log4j.message.StringFormatterMessageFactory; import org.apache.logging.log4j.message.StructuredDataMessage; -import org.apache.logging.log4j.spi.LoggingSystem; import org.awaitility.Awaitility; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Tag; @@ -63,16 +62,16 @@ public class LoggerTest { static final String CONFIG = "log4j-test2.xml"; - private static void checkMessageFactory(final MessageFactory messageFactory, final Logger testLogger) { + private void checkMessageFactory(final MessageFactory messageFactory, final Logger testLogger) { if (messageFactory == null) { - assertSame(LoggingSystem.getMessageFactory(), testLogger.getMessageFactory()); + assertSame(defaultMessageFactory, testLogger.getMessageFactory()); } else { final MessageFactory actual = testLogger.getMessageFactory(); assertEquals(messageFactory, actual); } } - private static Logger testMessageFactoryMismatch( + private Logger testMessageFactoryMismatch( final String name, final MessageFactory messageFactory1, final MessageFactory messageFactory2) { final Logger testLogger1 = (Logger) LogManager.getLogger(name, messageFactory1); assertNotNull(testLogger1); @@ -86,6 +85,7 @@ public class LoggerTest { org.apache.logging.log4j.Logger logger; org.apache.logging.log4j.Logger loggerChild; org.apache.logging.log4j.Logger loggerGrandchild; + MessageFactory defaultMessageFactory; private final ListAppender app; private final ListAppender host; @@ -100,6 +100,7 @@ public class LoggerTest { logger = context.getLogger("LoggerTest"); loggerChild = context.getLogger("LoggerTest.child"); loggerGrandchild = context.getLogger("LoggerTest.child.grand"); + defaultMessageFactory = context.getInstanceFactory().getInstance(MessageFactory.class); this.app = app.clear(); this.host = host.clear(); this.noThrown = noThrown.clear(); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java index 40c39ed3f7..92562cf418 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingAppenderDirectWriteStartupSizeTest.java @@ -20,8 +20,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.apache.logging.log4j.core.appender.RollingFileAppender; +import org.apache.logging.log4j.core.test.junit.CleanFolders; import org.apache.logging.log4j.core.test.junit.LoggerContextRule; -import org.apache.logging.log4j.test.junit.CleanFolders; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Rule; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java index aaabecf8b2..156c85e8f0 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/rolling/RollingFileAppenderInterruptedThreadTest.java @@ -29,7 +29,7 @@ import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; -import org.apache.logging.log4j.test.junit.CleanFolders; +import org.apache.logging.log4j.core.test.junit.CleanFolders; import org.junit.After; import org.junit.Assert; import org.junit.Before; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java index ff00480783..c35d078071 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/async/AsyncQueueFullPolicyFactoryTest.java @@ -22,7 +22,6 @@ import static org.assertj.core.api.Assertions.assertThat; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.impl.PropertyKeys; -import org.apache.logging.log4j.test.junit.Tags; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java index 1b692f77fa..89577432fc 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/config/TestConfiguratorError.java @@ -20,13 +20,10 @@ import static org.junit.jupiter.api.Assertions.assertNull; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.simple.SimpleLoggerContextFactory; -import org.apache.logging.log4j.spi.LoggingSystemProperty; import org.apache.logging.log4j.test.junit.LoggerContextFactoryExtension; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.api.parallel.ResourceLock; -@ResourceLock(LoggingSystemProperty.Constant.LOGGER_CONTEXT_FACTORY_CLASS) public class TestConfiguratorError { @RegisterExtension diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java index 7ea70a4614..7d9fae8121 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjectorTest.java @@ -38,6 +38,7 @@ import org.apache.logging.log4j.core.ContextDataInjector; import org.apache.logging.log4j.spi.LoggingSystem; import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap; import org.apache.logging.log4j.spi.ThreadContextMap; +import org.apache.logging.log4j.util.ProviderUtil; import org.apache.logging.log4j.util.SortedArrayStringMap; import org.apache.logging.log4j.util.StringMap; import org.junit.After; @@ -122,7 +123,7 @@ public class ThreadContextDataInjectorTest { } private void prepareThreadContext(final boolean isThreadContextMapInheritable) { - LoggingSystem.getProvider() + ProviderUtil.getProvider() .setThreadContextMapFactory(threadContextMapConstructor.apply(isThreadContextMapInheritable)); ThreadContext.init(); ThreadContext.remove("baz"); diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelectorTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelectorTest.java index 00b013af94..1d31f1f197 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelectorTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/selector/ClassLoaderContextSelectorTest.java @@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertNotSame; import java.lang.reflect.Field; import org.apache.logging.log4j.core.Logger; -import org.apache.logging.log4j.util.ReflectionUtil; +import org.apache.logging.log4j.plugins.util.ReflectionUtil; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java index e3343a1ea5..5932d113fa 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateCustomLoggerTest.java @@ -38,9 +38,9 @@ import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.test.TestConstants; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.MessageFactory; -import org.apache.logging.log4j.spi.LoggingSystemProperty; import org.apache.logging.log4j.test.TestLogger; import org.apache.logging.log4j.util.MessageSupplier; import org.apache.logging.log4j.util.Strings; @@ -52,7 +52,7 @@ import org.junitpioneer.jupiter.SetSystemProperty; @Tag("functional") @SetSystemProperty( - key = LoggingSystemProperty.Constant.LOGGER_CONTEXT_FACTORY_CLASS, + key = TestConstants.LOGGER_CONTEXT_FACTORY, value = "org.apache.logging.log4j.test.TestLoggerContextFactory") public class GenerateCustomLoggerTest { diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java index 35f746d38e..cb8f49afbf 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java +++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/tools/GenerateExtendedLoggerTest.java @@ -38,10 +38,10 @@ import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.core.test.TestConstants; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.MessageFactory; import org.apache.logging.log4j.spi.ExtendedLogger; -import org.apache.logging.log4j.spi.LoggingSystemProperty; import org.apache.logging.log4j.test.TestLogger; import org.apache.logging.log4j.util.MessageSupplier; import org.apache.logging.log4j.util.Strings; @@ -53,7 +53,7 @@ import org.junitpioneer.jupiter.SetSystemProperty; @Tag("functional") @SetSystemProperty( - key = LoggingSystemProperty.Constant.LOGGER_CONTEXT_FACTORY_CLASS, + key = TestConstants.LOGGER_CONTEXT_FACTORY, value = "org.apache.logging.log4j.test.TestLoggerContextFactory") public class GenerateExtendedLoggerTest { diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonUtilsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonUtilsTest.java deleted file mode 100644 index 5f035e6239..0000000000 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonUtilsTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.logging.log4j.core.util; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -/** - * This class is borrowed from <a href="https://github.com/FasterXML/jackson-core">Jackson</a>. - */ -public class JsonUtilsTest { - - @Test - public void testQuoteCharSequenceAsString() throws Exception { - final StringBuilder output = new StringBuilder(); - final StringBuilder builder = new StringBuilder(); - builder.append("foobar"); - JsonUtils.quoteAsString(builder, output); - assertEquals("foobar", output.toString()); - builder.setLength(0); - output.setLength(0); - builder.append("\"x\""); - JsonUtils.quoteAsString(builder, output); - assertEquals("\\\"x\\\"", output.toString()); - } - - // For [JACKSON-853] - @Test - public void testQuoteLongCharSequenceAsString() throws Exception { - final StringBuilder output = new StringBuilder(); - final StringBuilder input = new StringBuilder(); - final StringBuilder sb2 = new StringBuilder(); - for (int i = 0; i < 1111; ++i) { - input.append('"'); - sb2.append("\\\""); - } - final String exp = sb2.toString(); - JsonUtils.quoteAsString(input, output); - assertEquals(2 * input.length(), output.length()); - assertEquals(exp, output.toString()); - } - - // [JACKSON-884] - @Test - public void testCharSequenceWithCtrlChars() throws Exception { - final char[] input = new char[] {0, 1, 2, 3, 4}; - final StringBuilder builder = new StringBuilder(); - builder.append(input); - final StringBuilder output = new StringBuilder(); - JsonUtils.quoteAsString(builder, output); - assertEquals("\\u0000\\u0001\\u0002\\u0003\\u0004", output.toString()); - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java index 3949f3c0f8..8942e2242b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/LoggerContext.java @@ -65,7 +65,6 @@ import org.apache.logging.log4j.spi.LoggerContextFactory; import org.apache.logging.log4j.spi.LoggerContextShutdownAware; import org.apache.logging.log4j.spi.LoggerContextShutdownEnabled; import org.apache.logging.log4j.spi.LoggerRegistry; -import org.apache.logging.log4j.spi.LoggingSystem; import org.apache.logging.log4j.spi.Terminable; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.Lazy; @@ -89,7 +88,7 @@ public class LoggerContext extends AbstractLifeCycle private final LoggerRegistry<Logger> loggerRegistry = new LoggerRegistry<>(); private final Collection<Consumer<Configuration>> configurationStartedListeners = new ArrayList<>(); private final Collection<Consumer<Configuration>> configurationStoppedListeners = new ArrayList<>(); - private final Lazy<List<LoggerContextShutdownAware>> listeners = Lazy.relaxed(CopyOnWriteArrayList::new); + private final Lazy<List<LoggerContextShutdownAware>> listeners = Lazy.lazy(CopyOnWriteArrayList::new); private final ConfigurableInstanceFactory instanceFactory; private final PropertyEnvironment environment; private final ConfigurationScheduler configurationScheduler; @@ -126,8 +125,11 @@ public class LoggerContext extends AbstractLifeCycle this.instanceFactory = Objects.requireNonNull(instanceFactory); this.instanceFactory.registerBinding(KEY, Lazy.weak(this)); // Post-process the factory, after registering itself - ServiceLoaderUtil.safeStream(ServiceLoader.load( - ConfigurableInstanceFactoryPostProcessor.class, LoggerContext.class.getClassLoader())) + ServiceLoaderUtil.safeStream( + ConfigurableInstanceFactoryPostProcessor.class, + ServiceLoader.load( + ConfigurableInstanceFactoryPostProcessor.class, LoggerContext.class.getClassLoader()), + LOGGER) .sorted(Comparator.comparing( ConfigurableInstanceFactoryPostProcessor::getClass, OrderedComparator.INSTANCE)) .forEachOrdered(processor -> processor.postProcessFactory(instanceFactory)); @@ -175,15 +177,15 @@ public class LoggerContext extends AbstractLifeCycle /** * Checks that the message factory a logger was created with is the same as the given messageFactory. If they are * different log a warning to the {@linkplain StatusLogger}. A null MessageFactory translates to the default - * MessageFactory {@link LoggingSystem#getMessageFactory()}. + * MessageFactory. * * @param logger The logger to check * @param messageFactory The message factory to check. */ - public static void checkMessageFactory(final ExtendedLogger logger, final MessageFactory messageFactory) { + public void checkMessageFactory(final ExtendedLogger logger, final MessageFactory messageFactory) { final String name = logger.getName(); final MessageFactory loggerMessageFactory = logger.getMessageFactory(); - final MessageFactory currentMessageFactory = LoggingSystem.getMessageFactory(); + final MessageFactory currentMessageFactory = instanceFactory.getInstance(MessageFactory.class); if (messageFactory != null && !loggerMessageFactory.equals(messageFactory)) { StatusLogger.getLogger() .warn( @@ -204,7 +206,6 @@ public class LoggerContext extends AbstractLifeCycle } } - @Override public PropertyEnvironment getEnvironment() { return environment; } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java index cc6bc34b20..4778e90b34 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileManager.java @@ -36,7 +36,7 @@ import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.util.Closer; import org.apache.logging.log4j.core.util.FileUtils; -import org.apache.logging.log4j.util.ReflectionUtil; +import org.apache.logging.log4j.plugins.util.ReflectionUtil; // Lines too long... // CHECKSTYLE:OFF diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java index 7d56d0325b..30ada6eacb 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java @@ -82,7 +82,6 @@ import org.apache.logging.log4j.plugins.model.PluginType; import org.apache.logging.log4j.plugins.util.OrderedComparator; import org.apache.logging.log4j.util.Cast; import org.apache.logging.log4j.util.Lazy; -import org.apache.logging.log4j.util.NameUtil; import org.apache.logging.log4j.util.ServiceLoaderUtil; import org.apache.logging.log4j.util.Strings; import org.jspecify.annotations.NullMarked; @@ -188,12 +187,16 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement this.configurationScheduler = parentInstanceFactory.getInstance(ConfigurationScheduler.class); this.environment = environment; this.instanceFactory = parentInstanceFactory.newChildInstanceFactory(); - this.watchManager = new WatchManager(configurationScheduler); + this.watchManager = new WatchManager(configurationScheduler, LOGGER); configurationProcessor = new ConfigurationProcessor(instanceFactory); instanceFactory.registerBinding(Configuration.KEY, Lazy.weak(this)); - ServiceLoaderUtil.safeStream(ServiceLoader.load( - ConfigurableInstanceFactoryPostProcessor.class, AbstractConfiguration.class.getClassLoader())) + // Post-process the factory, after registering itself + ServiceLoaderUtil.safeStream( + ConfigurableInstanceFactoryPostProcessor.class, + ServiceLoader.load( + ConfigurableInstanceFactoryPostProcessor.class, LoggerContext.class.getClassLoader()), + LOGGER) .sorted(Comparator.comparing( ConfigurableInstanceFactoryPostProcessor::getClass, OrderedComparator.INSTANCE)) .forEachOrdered(processor -> processor.postProcessFactory(instanceFactory)); @@ -298,8 +301,11 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement private void initializeScriptManager() { try { - ServiceLoaderUtil.safeStream(ServiceLoader.load( - ScriptManagerFactory.class, AbstractConfiguration.class.getClassLoader())) + ServiceLoaderUtil.safeStream( + ScriptManagerFactory.class, + ServiceLoader.load( + ScriptManagerFactory.class, AbstractConfiguration.class.getClassLoader()), + LOGGER) .findFirst() .ifPresent(factory -> setScriptManager(factory.createScriptManager(this, getWatchManager()))); } catch (final LinkageError | Exception e) { @@ -1037,7 +1043,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement return loggerConfig; } String substr = loggerName; - while ((substr = NameUtil.getSubName(substr)) != null) { + while ((substr = getSubName(substr)) != null) { loggerConfig = loggerConfigs.get(substr); if (loggerConfig != null) { return loggerConfig; @@ -1046,6 +1052,14 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement return root; } + private static @Nullable String getSubName(final String name) { + if (Strings.isEmpty(name)) { + return null; + } + final int i = name.lastIndexOf('.'); + return i > 0 ? name.substring(0, i) : Strings.EMPTY; + } + @Override public LoggerContext getLoggerContext() { return loggerContext.get(); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfigurationFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfigurationFactory.java index 84dfa13ce8..3f41e022b1 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfigurationFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/DefaultConfigurationFactory.java @@ -32,7 +32,6 @@ import org.apache.logging.log4j.core.lookup.StrSubstitutor; import org.apache.logging.log4j.core.util.NetUtils; import org.apache.logging.log4j.kit.env.PropertyEnvironment; import org.apache.logging.log4j.plugins.di.InstanceFactory; -import org.apache.logging.log4j.spi.LoggingSystemProperty; import org.apache.logging.log4j.util.LoaderUtil; import org.apache.logging.log4j.util.Strings; @@ -156,10 +155,9 @@ public class DefaultConfigurationFactory extends ConfigurationFactory { "No Log4j 2 configuration file found. " + "Using default configuration (logging only errors to the console), " + "or user programmatically provided configurations. " - + "Set system property 'log4j2.*.{}' " + + "Set system property 'log4j2.debug' " + "to show Log4j 2 internal initialization logging. " - + "See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2", - LoggingSystemProperty.STATUS_LOGGER_DEBUG); + + "See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2"); return new DefaultConfiguration(loggerContext); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java index fa95c0c8aa..7581dcdc38 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/NullConfiguration.java @@ -18,8 +18,8 @@ package org.apache.logging.log4j.core.config; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.kit.env.PropertyEnvironment; import org.apache.logging.log4j.plugins.di.DI; -import org.apache.logging.log4j.util.PropertiesUtil; /** * This configuration defaults to no logging. @@ -36,7 +36,7 @@ public class NullConfiguration extends AbstractConfiguration { */ @Deprecated public NullConfiguration() { - super(null, ConfigurationSource.NULL_SOURCE, PropertiesUtil.getProperties(), DI.createInitializedFactory()); + super(null, ConfigurationSource.NULL_SOURCE, PropertyEnvironment.getGlobal(), DI.createInitializedFactory()); setName(NULL_NAME); final LoggerConfig root = getRootLogger(); root.setLevel(Level.OFF); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java index 1f561b8c31..110da066c6 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/builder/impl/BuiltConfiguration.java @@ -25,11 +25,11 @@ import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.Reconfigurable; import org.apache.logging.log4j.core.config.builder.api.Component; import org.apache.logging.log4j.core.config.status.StatusConfiguration; +import org.apache.logging.log4j.kit.env.PropertyEnvironment; import org.apache.logging.log4j.plugins.Node; import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory; import org.apache.logging.log4j.plugins.di.DI; import org.apache.logging.log4j.plugins.model.PluginType; -import org.apache.logging.log4j.util.PropertiesUtil; import org.jspecify.annotations.Nullable; /** @@ -56,7 +56,7 @@ public class BuiltConfiguration extends AbstractConfiguration { super( loggerContext, source, - loggerContext != null ? loggerContext.getEnvironment() : PropertiesUtil.getProperties(), + loggerContext != null ? loggerContext.getEnvironment() : PropertyEnvironment.getGlobal(), loggerContext != null ? (ConfigurableInstanceFactory) loggerContext.getInstanceFactory() : DI.createInitializedFactory()); diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java index 0698962d20..5c39290706 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/json/JsonConfiguration.java @@ -30,10 +30,10 @@ import org.apache.logging.log4j.core.config.ConfigurationSource; import org.apache.logging.log4j.core.config.LoggerConfig; import org.apache.logging.log4j.core.config.Reconfigurable; import org.apache.logging.log4j.core.config.status.StatusConfiguration; +import org.apache.logging.log4j.kit.json.JsonReader; import org.apache.logging.log4j.plugins.Node; import org.apache.logging.log4j.plugins.model.PluginType; import org.apache.logging.log4j.util.Cast; -import org.apache.logging.log4j.util.JsonReader; public class JsonConfiguration extends AbstractConfiguration implements Reconfigurable { diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilter.java index 1b66b55853..d9d1ea156b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/filter/MutableThreadContextMapFilter.java @@ -47,13 +47,13 @@ import org.apache.logging.log4j.core.util.internal.HttpInputStreamUtil; import org.apache.logging.log4j.core.util.internal.LastModifiedSource; import org.apache.logging.log4j.core.util.internal.Status; import org.apache.logging.log4j.kit.env.PropertyEnvironment; +import org.apache.logging.log4j.kit.json.JsonReader; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.plugins.Configurable; import org.apache.logging.log4j.plugins.Plugin; import org.apache.logging.log4j.plugins.PluginAliases; import org.apache.logging.log4j.plugins.PluginAttribute; import org.apache.logging.log4j.plugins.PluginFactory; -import org.apache.logging.log4j.util.JsonReader; import org.apache.logging.log4j.util.PerformanceSensitive; /** diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java index 206e8bb7dd..d5a74a669b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/DefaultBundle.java @@ -16,8 +16,12 @@ */ package org.apache.logging.log4j.core.impl; +import java.util.Comparator; import java.util.Map; +import java.util.Optional; +import java.util.ServiceLoader; import java.util.function.Supplier; +import java.util.stream.Stream; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; @@ -40,9 +44,14 @@ import org.apache.logging.log4j.core.time.NanoClock; import org.apache.logging.log4j.core.time.internal.DummyNanoClock; import org.apache.logging.log4j.core.util.DefaultShutdownCallbackRegistry; import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry; +import org.apache.logging.log4j.kit.env.PropertyEnvironment; import org.apache.logging.log4j.kit.recycler.RecyclerFactory; +import org.apache.logging.log4j.kit.recycler.RecyclerFactoryProvider; +import org.apache.logging.log4j.kit.recycler.RecyclerKeys; +import org.apache.logging.log4j.message.DefaultFlowMessageFactory; import org.apache.logging.log4j.message.FlowMessageFactory; import org.apache.logging.log4j.message.MessageFactory; +import org.apache.logging.log4j.message.ReusableMessageFactory; import org.apache.logging.log4j.plugins.Named; import org.apache.logging.log4j.plugins.Namespace; import org.apache.logging.log4j.plugins.SingletonFactory; @@ -50,10 +59,10 @@ import org.apache.logging.log4j.plugins.condition.ConditionalOnMissingBinding; import org.apache.logging.log4j.plugins.di.ConfigurableInstanceFactory; import org.apache.logging.log4j.spi.CopyOnWrite; import org.apache.logging.log4j.spi.LoggerContextFactory; -import org.apache.logging.log4j.spi.LoggingSystem; import org.apache.logging.log4j.spi.Provider; import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap; import org.apache.logging.log4j.status.StatusLogger; +import org.apache.logging.log4j.util.ServiceLoaderUtil; /** * Provides instance binding defaults. @@ -85,19 +94,36 @@ public class DefaultBundle { @SingletonFactory @ConditionalOnMissingBinding public MessageFactory defaultMessageFactory() { - return LoggingSystem.getMessageFactory(); + return new ReusableMessageFactory(); } @SingletonFactory @ConditionalOnMissingBinding - public FlowMessageFactory defaultFlowMessageFactory() { - return LoggingSystem.getFlowMessageFactory(); + public FlowMessageFactory defaultFlowMessageFactory(MessageFactory messageFactory) { + return new DefaultFlowMessageFactory(messageFactory); } @SingletonFactory @ConditionalOnMissingBinding - public RecyclerFactory defaultRecyclerFactory() { - return LoggingSystem.getRecyclerFactory(); + public RecyclerFactoryProvider defaultRecyclerFactoryProvider( + final PropertyEnvironment environment, + final ClassLoader loader, + final @Named("StatusLogger") org.apache.logging.log4j.Logger statusLogger) { + final String factory = + environment.getProperty(RecyclerKeys.Recycler.class).factory(); + final Stream<RecyclerFactoryProvider> providerStream = ServiceLoaderUtil.safeStream( + RecyclerFactoryProvider.class, ServiceLoader.load(RecyclerFactoryProvider.class, loader), statusLogger); + final Optional<RecyclerFactoryProvider> provider = factory != null + ? providerStream.filter(p -> factory.equals(p.getName())).findAny() + : providerStream.min(Comparator.comparing(RecyclerFactoryProvider::getOrder)); + return provider.orElseGet(RecyclerFactoryProvider::getInstance); + } + + @SingletonFactory + @ConditionalOnMissingBinding + public RecyclerFactory defaultRecyclerFactory( + final PropertyEnvironment environment, final RecyclerFactoryProvider provider) { + return provider.createForEnvironment(environment); } @SingletonFactory diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java index 1fa91bc65b..3c31b89cc5 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jContextFactory.java @@ -16,8 +16,6 @@ */ package org.apache.logging.log4j.core.impl; -import static org.apache.logging.log4j.util.Constants.isWebApp; - import java.net.URI; import java.util.ArrayList; import java.util.List; @@ -40,6 +38,7 @@ import org.apache.logging.log4j.plugins.di.DI; import org.apache.logging.log4j.plugins.di.Key; import org.apache.logging.log4j.spi.LoggerContextFactory; import org.apache.logging.log4j.status.StatusLogger; +import org.apache.logging.log4j.util.Constants; import org.apache.logging.log4j.util.StackLocatorUtil; import org.jspecify.annotations.NullMarked; @@ -57,7 +56,7 @@ public class Log4jContextFactory implements LoggerContextFactory, ShutdownCallba private final ShutdownCallbackRegistry shutdownCallbackRegistry; /** - * Initializes the ContextSelector from system property {@link Log4jPropertyKey#CONTEXT_SELECTOR_CLASS_NAME}. + * Initializes the ContextSelector from system properties. * <p> * Only used if no {@link org.apache.logging.log4j.spi.Provider} is present. * </p> @@ -431,15 +430,9 @@ public class Log4jContextFactory implements LoggerContextFactory, ShutdownCallba } public boolean isShutdownHookEnabled() { - return !isWebApp() + return !Constants.IS_WEB_APP && PropertyEnvironment.getGlobal() .getProperty(PropertyKeys.LoggerContext.class) .shutdownHookEnabled(); } - - @Override - public org.apache.logging.log4j.spi.LoggerContext wrapLoggerContext( - org.apache.logging.log4j.spi.LoggerContext loggerContext) { - return loggerContext; - } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jProvider.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jProvider.java index e0f91dbb64..bc07f62eb9 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jProvider.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/Log4jProvider.java @@ -46,7 +46,7 @@ public class Log4jProvider extends Provider { } @Override - public LoggerContextFactory getLoggerContextFactory() { + protected LoggerContextFactory createLoggerContextFactory() { return instanceFactory.getInstance(Key.forClass(LoggerContextFactory.class)); } } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/PropertyKeys.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/PropertyKeys.java index 0d21bbc0f8..29d5e814d1 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/PropertyKeys.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/PropertyKeys.java @@ -29,6 +29,7 @@ import org.apache.logging.log4j.core.util.AuthorizationProvider; import org.apache.logging.log4j.core.util.ShutdownCallbackRegistry; import org.apache.logging.log4j.kit.env.Log4jProperty; import org.apache.logging.log4j.message.MessageFactory; +import org.apache.logging.log4j.spi.LoggerContextFactory; import org.apache.logging.log4j.spi.ThreadContextMap; import org.apache.logging.log4j.util.StringMap; import org.jspecify.annotations.Nullable; @@ -141,6 +142,7 @@ public final class PropertyKeys { @Log4jProperty public record LoggerContext( + @Nullable Class<? extends LoggerContextFactory> factory, @Nullable Class<? extends ContextSelector> selector, @Nullable Class<? extends ShutdownCallbackRegistry> shutdownCallbackRegistry, @Log4jProperty(defaultValue = "true") boolean shutdownHookEnabled, diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java index 24d8604bca..7b36d1b762 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java @@ -31,6 +31,7 @@ import org.apache.logging.log4j.core.ContextDataInjector; import org.apache.logging.log4j.core.config.Property; import org.apache.logging.log4j.core.util.ContextDataProvider; import org.apache.logging.log4j.spi.ReadOnlyThreadContextMap; +import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.ReadOnlyStringMap; import org.apache.logging.log4j.util.ServiceLoaderUtil; import org.apache.logging.log4j.util.StringMap; @@ -64,11 +65,12 @@ public class ThreadContextDataInjector { final List<ContextDataProvider> providers = new ArrayList<>(); final ServiceLoader<ContextDataProvider> serviceLoader = ServiceLoader.load(ContextDataProvider.class, ThreadContextDataInjector.class.getClassLoader()); - ServiceLoaderUtil.safeStream(serviceLoader).forEachOrdered(provider -> { - if (providers.stream().noneMatch((p) -> p.getClass().isAssignableFrom(provider.getClass()))) { - providers.add(provider); - } - }); + ServiceLoaderUtil.safeStream(ContextDataProvider.class, serviceLoader, StatusLogger.getLogger()) + .forEachOrdered(provider -> { + if (providers.stream().noneMatch((p) -> p.getClass().isAssignableFrom(provider.getClass()))) { + providers.add(provider); + } + }); return Collections.unmodifiableList(providers); } diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java deleted file mode 100644 index ad86c88089..0000000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/JsonUtils.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to you under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.logging.log4j.core.util; - -import org.apache.logging.log4j.kit.recycler.Recycler; -import org.apache.logging.log4j.spi.LoggingSystem; -import org.apache.logging.log4j.util.Lazy; - -/** - * This class is borrowed from <a href="https://github.com/FasterXML/jackson-core">Jackson</a>. - */ -public final class JsonUtils { - - private static final char[] HC = "0123456789ABCDEF".toCharArray(); - - /** - * Read-only encoding table for first 128 Unicode code points (single-byte UTF-8 characters). - * Value of 0 means "no escaping"; other positive values that value is character - * to use after backslash; and negative values that generic (backslash - u) - * escaping is to be used. - */ - private static final Lazy<int[]> ESC_CODES = Lazy.pure(() -> { - final int[] table = new int[128]; - // Control chars need generic escape sequence - for (int i = 0; i < 32; ++i) { - // 04-Mar-2011, tatu: Used to use "-(i + 1)", replaced with constant - table[i] = -1; - } - /* Others (and some within that range too) have explicit shorter - * sequences - */ - table['"'] = '"'; - table['\\'] = '\\'; - // Escaping of slash is optional, so let's not add it - table[0x08] = 'b'; - table[0x09] = 't'; - table[0x0C] = 'f'; - table[0x0A] = 'n'; - table[0x0D] = 'r'; - return table; - }); - - /** - * Temporary buffer used for composing quote/escape sequences - */ - private static final Recycler<char[]> qbufRecycler = LoggingSystem.getRecyclerFactory() - .create(() -> { - char[] qbuf = new char[6]; - qbuf[0] = '\\'; - qbuf[2] = '0'; - qbuf[3] = '0'; - return qbuf; - }); - - /** - * Quote text contents using JSON standard quoting, and append results to a supplied {@link StringBuilder}. - */ - public static void quoteAsString(final CharSequence input, final StringBuilder output) { - final char[] qbuf = qbufRecycler.acquire(); - try { - final int[] escCodes = ESC_CODES.get(); - final int escCodeCount = escCodes.length; - int inPtr = 0; - final int inputLen = input.length(); - - outer: - while (inPtr < inputLen) { - tight_loop: - while (true) { - final char c = input.charAt(inPtr); - if (c < escCodeCount && escCodes[c] != 0) { - break tight_loop; - } - output.append(c); - if (++inPtr >= inputLen) { - break outer; - } - } - // something to escape; 2 or 6-char variant? - final char d = input.charAt(inPtr++); - final int escCode = escCodes[d]; - final int length = (escCode < 0) ? _appendNumeric(d, qbuf) : _appendNamed(escCode, qbuf); - - output.append(qbuf, 0, length); - } - } finally { - qbufRecycler.release(qbuf); - } - } - - private static int _appendNumeric(final int value, final char[] qbuf) { - qbuf[1] = 'u'; - // We know it's a control char, so only the last 2 chars are non-0 - qbuf[4] = HC[value >> 4]; - qbuf[5] = HC[value & 0xF]; - return 6; - } - - private static int _appendNamed(final int esc, final char[] qbuf) { - qbuf[1] = (char) esc; - return 2; - } -} diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java index f060e9f230..1efc5395c8 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java @@ -22,7 +22,6 @@ import java.net.URL; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.impl.PropertyKeys; import org.apache.logging.log4j.kit.env.PropertyEnvironment; -import org.apache.logging.log4j.spi.LoggingSystemProperty; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.LoaderUtil; @@ -297,7 +296,8 @@ public final class Loader { } /** - * Loads a class by name. This method respects the {@link LoggingSystemProperty#LOADER_IGNORE_THREAD_CONTEXT_LOADER} Log4j property. If this property is + * Loads a class by name. This method respects the {@link PropertyKeys.Loader#ignoreTCL()} Log4j property. If this + * property is * specified and set to anything besides {@code false}, then the default ClassLoader will be used. * * @param className The class name. diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java index 6df54530bd..1798920605 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/WatchManager.java @@ -37,6 +37,7 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.core.AbstractLifeCycle; import org.apache.logging.log4j.core.config.ConfigurationScheduler; import org.apache.logging.log4j.plugins.Inject; +import org.apache.logging.log4j.plugins.Named; import org.apache.logging.log4j.plugins.Singleton; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.ServiceLoaderUtil; @@ -144,10 +145,14 @@ public class WatchManager extends AbstractLifeCycle { private final ConcurrentMap<Source, ConfigurationMonitor> watchers = new ConcurrentHashMap<>(); @Inject - public WatchManager(final ConfigurationScheduler scheduler) { + public WatchManager( + final ConfigurationScheduler scheduler, + final @Named("StatusLogger") org.apache.logging.log4j.Logger statusLogger) { this.scheduler = Objects.requireNonNull(scheduler, "scheduler"); eventServiceList = ServiceLoaderUtil.safeStream( - ServiceLoader.load(WatchEventService.class, WatchManager.class.getClassLoader())) + WatchEventService.class, + ServiceLoader.load(WatchEventService.class, WatchManager.class.getClassLoader()), + statusLogger) .collect(Collectors.toList()); } diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/JsonReader.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/JsonReader.java similarity index 99% rename from log4j-api/src/main/java/org/apache/logging/log4j/util/JsonReader.java rename to log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/JsonReader.java index 9d1de4b1df..fe0416dba3 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/util/JsonReader.java +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/JsonReader.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.logging.log4j.util; +package org.apache.logging.log4j.kit.json; import java.math.BigDecimal; import java.math.BigInteger; diff --git a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/package-info.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/package-info.java new file mode 100644 index 0000000000..c50e64d810 --- /dev/null +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/json/package-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache license, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the license for the specific language governing permissions and + * limitations under the license. + */ +@Export +@Version("3.0.0") +package org.apache.logging.log4j.kit.json; + +import org.osgi.annotation.bundle.Export; +import org.osgi.annotation.versioning.Version; diff --git a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerFactoryProvider.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerFactoryProvider.java index ae8e140134..26ebd5900e 100644 --- a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerFactoryProvider.java +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerFactoryProvider.java @@ -18,6 +18,7 @@ package org.apache.logging.log4j.kit.recycler; import edu.umd.cs.findbugs.annotations.Nullable; import org.apache.logging.log4j.kit.env.PropertyEnvironment; +import org.apache.logging.log4j.kit.recycler.internal.DummyRecyclerFactoryProvider; /** * Contract for providing {@link RecyclerFactory} instances. @@ -26,6 +27,10 @@ import org.apache.logging.log4j.kit.env.PropertyEnvironment; */ public interface RecyclerFactoryProvider { + static RecyclerFactoryProvider getInstance() { + return DummyRecyclerFactoryProvider.INSTANCE; + } + /** * Denotes the value to be used while sorting recycler factory providers to determine the precedence order. * Values will be sorted naturally, that is, lower values will imply higher precedence. diff --git a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/PropertyKeys.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerKeys.java similarity index 97% rename from log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/PropertyKeys.java rename to log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerKeys.java index 77b1d06939..bc51e71014 100644 --- a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/PropertyKeys.java +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/RecyclerKeys.java @@ -19,7 +19,7 @@ package org.apache.logging.log4j.kit.recycler; import org.apache.logging.log4j.kit.env.Log4jProperty; import org.jspecify.annotations.Nullable; -public class PropertyKeys { +public class RecyclerKeys { /** * A set of common configuration options for recyclers diff --git a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/DummyRecyclerFactoryProvider.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/DummyRecyclerFactoryProvider.java index 0922bb2d03..8a58bbcac0 100644 --- a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/DummyRecyclerFactoryProvider.java +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/DummyRecyclerFactoryProvider.java @@ -35,6 +35,8 @@ import org.apache.logging.log4j.kit.recycler.support.AbstractRecycler; @ServiceProvider(RecyclerFactoryProvider.class) public final class DummyRecyclerFactoryProvider implements RecyclerFactoryProvider { + public static final RecyclerFactoryProvider INSTANCE = new DummyRecyclerFactoryProvider(); + @Override public int getOrder() { return 900; diff --git a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/ThreadLocalRecyclerFactoryProvider.java b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/ThreadLocalRecyclerFactoryProvider.java index 23af67bec1..2fc3d681bc 100644 --- a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/ThreadLocalRecyclerFactoryProvider.java +++ b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/ThreadLocalRecyclerFactoryProvider.java @@ -25,10 +25,10 @@ import java.util.Queue; import java.util.function.Consumer; import java.util.function.Supplier; import org.apache.logging.log4j.kit.env.PropertyEnvironment; -import org.apache.logging.log4j.kit.recycler.PropertyKeys; import org.apache.logging.log4j.kit.recycler.Recycler; import org.apache.logging.log4j.kit.recycler.RecyclerFactory; import org.apache.logging.log4j.kit.recycler.RecyclerFactoryProvider; +import org.apache.logging.log4j.kit.recycler.RecyclerKeys; import org.apache.logging.log4j.kit.recycler.support.AbstractRecycler; /** @@ -60,7 +60,7 @@ public final class ThreadLocalRecyclerFactoryProvider implements RecyclerFactory public RecyclerFactory createForEnvironment(final PropertyEnvironment environment) { requireNonNull(environment, "environment"); final Integer capacity = - environment.getProperty(PropertyKeys.Recycler.class).capacity(); + environment.getProperty(RecyclerKeys.Recycler.class).capacity(); if (capacity != null && capacity < 1) { throw new IllegalArgumentException("was expecting a `capacity` greater than 1, found: " + capacity); } diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonReaderTest.java b/log4j-kit/src/test/java/org/apache/logging/log4j/kit/json/JsonReaderTest.java similarity index 99% rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonReaderTest.java rename to log4j-kit/src/test/java/org/apache/logging/log4j/kit/json/JsonReaderTest.java index b4bb32ff1a..1e9698c429 100644 --- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/util/JsonReaderTest.java +++ b/log4j-kit/src/test/java/org/apache/logging/log4j/kit/json/JsonReaderTest.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.logging.log4j.core.util; +package org.apache.logging.log4j.kit.json; import java.math.BigDecimal; import java.math.BigInteger; @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; -import org.apache.logging.log4j.util.JsonReader; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest;
