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

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


The following commit(s) were added to refs/heads/2.x-site-pro by this push:
     new ad1a5059eb Restore code to `2.24.1`
ad1a5059eb is described below

commit ad1a5059eb205dfb7fa95399ca6b34eae70f3b8d
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Mon Oct 21 11:27:10 2024 +0200

    Restore code to `2.24.1`
---
 .../apache/logging/log4j/message/package-info.java |   2 +-
 .../logging/log4j/simple/SimpleLoggerContext.java  |   8 +-
 .../apache/logging/log4j/spi/AbstractLogger.java   |   4 -
 .../apache/logging/log4j/spi/LoggerContext.java    |   7 +-
 .../apache/logging/log4j/spi/LoggerRegistry.java   |  88 +-------
 .../org/apache/logging/log4j/spi/package-info.java |   2 +-
 .../apache/logging/log4j/core/LoggerContext.java   |  13 +-
 .../log4j/core/appender/AbstractAppender.java      |   6 +-
 .../core/appender/HttpURLConnectionManager.java    |   3 +-
 .../logging/log4j/core/async/package-info.java     |   2 +-
 .../log4j/core/config/AbstractConfiguration.java   |  15 +-
 .../log4j/core/config/ConfigurationSource.java     |   9 +-
 .../apache/logging/log4j/core/net/SmtpManager.java |   3 +-
 .../logging/log4j/core/net/SslSocketManager.java   |  62 +-----
 .../log4j/core/net/UrlConnectionFactory.java       |   3 +-
 .../net/ssl/AbstractKeyStoreConfiguration.java     |   9 +-
 .../log4j/core/net/ssl/KeyStoreConfiguration.java  |   6 +-
 .../log4j/core/net/ssl/PasswordProvider.java       |   1 -
 .../log4j/core/net/ssl/SslConfiguration.java       | 240 +++++++++++++--------
 .../core/net/ssl/SslConfigurationFactory.java      |   3 +-
 .../log4j/core/net/ssl/StoreConfiguration.java     |   2 +-
 .../core/net/ssl/TrustStoreConfiguration.java      |   6 +-
 .../logging/log4j/core/net/ssl/package-info.java   |   2 +-
 .../apache/logging/log4j/core/package-info.java    |   2 +-
 .../org/apache/logging/log4j/core/util/Loader.java |   5 +-
 .../org/apache/logging/log4j/core/util/Source.java |  45 ++--
 .../log4j/core/util/datetime/FastDatePrinter.java  |   2 +-
 .../logging/log4j/core/util/package-info.java      |   2 +-
 .../org/apache/logging/log4j/smtp/SmtpManager.java |   3 +-
 .../log4j/taglib/Log4jTaglibLoggerContext.java     |  17 +-
 .../apache/logging/log4j/taglib/package-info.java  |   2 +-
 .../logging/log4j/tojul/JULLoggerContext.java      |  15 +-
 .../apache/logging/log4j/tojul/package-info.java   |   2 +-
 .../apache/logging/slf4j/SLF4JLoggerContext.java   |  15 +-
 .../org/apache/logging/slf4j/package-info.java     |   2 +-
 35 files changed, 259 insertions(+), 349 deletions(-)

diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
index fbec2d82f4..dae91264f4 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/package-info.java
@@ -19,7 +19,7 @@
  * Public Message Types used for Log4j 2. Users may implement their own 
Messages.
  */
 @Export
-@Version("2.24.2")
+@Version("2.24.1")
 package org.apache.logging.log4j.message;
 
 import org.osgi.annotation.bundle.Export;
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
index 4663cbc9c6..55cced06f5 100644
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
@@ -102,7 +102,13 @@ public class SimpleLoggerContext implements LoggerContext {
     public ExtendedLogger getLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
-        return loggerRegistry.computeIfAbsent(name, effectiveMessageFactory, 
this::createLogger);
+        final ExtendedLogger oldLogger = loggerRegistry.getLogger(name, 
effectiveMessageFactory);
+        if (oldLogger != null) {
+            return oldLogger;
+        }
+        final ExtendedLogger newLogger = createLogger(name, 
effectiveMessageFactory);
+        loggerRegistry.putIfAbsent(name, effectiveMessageFactory, newLogger);
+        return loggerRegistry.getLogger(name, effectiveMessageFactory);
     }
 
     private ExtendedLogger createLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
index 06d99f3f15..ecc499ac58 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLogger.java
@@ -166,11 +166,7 @@ public abstract class AbstractLogger implements 
ExtendedLogger, LocationAwareLog
      *
      * @param logger The logger to check
      * @param messageFactory The message factory to check.
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
-     * Instead, in {@link LoggerContext#getLogger(String, MessageFactory)} 
implementations, namespace loggers with message factories.
-     * If your implementation uses {@link LoggerRegistry}, you are already 
covered.
      */
-    @Deprecated
     public static void checkMessageFactory(final ExtendedLogger logger, final 
MessageFactory messageFactory) {
         final String name = logger.getName();
         final MessageFactory loggerMessageFactory = logger.getMessageFactory();
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
index 27874bded0..a14af967bf 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerContext.java
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.spi;
 
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.message.MessageFactory;
-import org.jspecify.annotations.Nullable;
 
 /**
  * Anchor point for logging implementations.
@@ -55,7 +54,7 @@ public interface LoggerContext {
      * @return The logger.
      * @since 2.14.0
      */
-    default ExtendedLogger getLogger(Class<?> cls, @Nullable MessageFactory 
messageFactory) {
+    default ExtendedLogger getLogger(Class<?> cls, MessageFactory 
messageFactory) {
         final String canonicalName = cls.getCanonicalName();
         return getLogger(canonicalName != null ? canonicalName : 
cls.getName(), messageFactory);
     }
@@ -74,7 +73,7 @@ public interface LoggerContext {
      *                       the logger but will log a warning if mismatched.
      * @return The logger with the specified name.
      */
-    ExtendedLogger getLogger(String name, @Nullable MessageFactory 
messageFactory);
+    ExtendedLogger getLogger(String name, MessageFactory messageFactory);
 
     /**
      * Gets the LoggerRegistry.
@@ -119,7 +118,7 @@ public interface LoggerContext {
      * @return true if the Logger exists, false otherwise.
      * @since 2.5
      */
-    boolean hasLogger(String name, @Nullable MessageFactory messageFactory);
+    boolean hasLogger(String name, MessageFactory messageFactory);
 
     /**
      * Associates an object into the LoggerContext by name for later use.
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
index 51519a33d0..d1ff7b9738 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerRegistry.java
@@ -30,17 +30,12 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.function.BiFunction;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.message.ParameterizedMessageFactory;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.jspecify.annotations.NullMarked;
-import org.jspecify.annotations.Nullable;
 
 /**
  * Convenience class to be used as an {@link ExtendedLogger} registry by 
{@code LoggerContext} implementations.
  */
-@NullMarked
 public class LoggerRegistry<T extends ExtendedLogger> {
 
     private final Map<String, Map<MessageFactory, WeakReference<T>>> 
loggerRefByMessageFactoryByName = new HashMap<>();
@@ -55,9 +50,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * Data structure contract for the internal storage of admitted loggers.
      *
      * @param <T> subtype of {@code ExtendedLogger}
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
      */
-    @Deprecated
     public interface MapFactory<T extends ExtendedLogger> {
 
         Map<String, T> createInnerMap();
@@ -71,9 +64,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * {@link MapFactory} implementation using {@link ConcurrentHashMap}.
      *
      * @param <T> subtype of {@code ExtendedLogger}
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
      */
-    @Deprecated
     public static class ConcurrentMapFactory<T extends ExtendedLogger> 
implements MapFactory<T> {
 
         @Override
@@ -96,9 +87,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * {@link MapFactory} implementation using {@link WeakHashMap}.
      *
      * @param <T> subtype of {@code ExtendedLogger}
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
      */
-    @Deprecated
     public static class WeakMapFactory<T extends ExtendedLogger> implements 
MapFactory<T> {
 
         @Override
@@ -123,10 +112,8 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * Constructs an instance <b>ignoring</b> the given the map factory.
      *
      * @param mapFactory a map factory
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
      */
-    @Deprecated
-    public LoggerRegistry(@Nullable final MapFactory<T> mapFactory) {
+    public LoggerRegistry(final MapFactory<T> mapFactory) {
         this();
     }
 
@@ -139,10 +126,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      *
      * @param name a logger name
      * @return the logger associated with the name
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
-     * Use {@link #getLogger(String, MessageFactory)} instead.
      */
-    @Deprecated
     public T getLogger(final String name) {
         requireNonNull(name, "name");
         return getLogger(name, null);
@@ -160,7 +144,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * @param messageFactory a message factory
      * @return the logger associated with the given name and message factory
      */
-    public T getLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public T getLogger(final String name, final MessageFactory messageFactory) 
{
         requireNonNull(name, "name");
         readLock.lock();
         try {
@@ -209,10 +193,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      *
      * @param name a logger name
      * @return {@code true}, if the logger exists; {@code false} otherwise.
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
-     * Use {@link #hasLogger(String, MessageFactory)} instead.
      */
-    @Deprecated
     public boolean hasLogger(final String name) {
         requireNonNull(name, "name");
         final T logger = getLogger(name);
@@ -232,7 +213,7 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * @return {@code true}, if the logger exists; {@code false} otherwise.
      * @since 2.5
      */
-    public boolean hasLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public boolean hasLogger(final String name, final MessageFactory 
messageFactory) {
         requireNonNull(name, "name");
         final T logger = getLogger(name, messageFactory);
         return logger != null;
@@ -265,12 +246,8 @@ public class LoggerRegistry<T extends ExtendedLogger> {
      * @param name ignored – kept for backward compatibility
      * @param messageFactory ignored – kept for backward compatibility
      * @param logger a logger instance
-     * @deprecated As of version {@code 2.25.0}, planned to be removed!
-     * Use {@link #computeIfAbsent(String, MessageFactory, BiFunction)} 
instead.
      */
-    @Deprecated
-    public void putIfAbsent(
-            @Nullable final String name, @Nullable final MessageFactory 
messageFactory, final T logger) {
+    public void putIfAbsent(final String name, final MessageFactory 
messageFactory, final T logger) {
 
         // Check arguments
         requireNonNull(logger, "logger");
@@ -278,10 +255,9 @@ public class LoggerRegistry<T extends ExtendedLogger> {
         // Insert the logger
         writeLock.lock();
         try {
-            final String loggerName = logger.getName();
             final Map<MessageFactory, WeakReference<T>> 
loggerRefByMessageFactory =
                     loggerRefByMessageFactoryByName.computeIfAbsent(
-                            loggerName, 
this::createLoggerRefByMessageFactoryMap);
+                            logger.getName(), 
this::createLoggerRefByMessageFactoryMap);
             final MessageFactory loggerMessageFactory = 
logger.getMessageFactory();
             final WeakReference<T> loggerRef = 
loggerRefByMessageFactory.get(loggerMessageFactory);
             if (loggerRef == null || loggerRef.get() == null) {
@@ -292,60 +268,6 @@ public class LoggerRegistry<T extends ExtendedLogger> {
         }
     }
 
-    public T computeIfAbsent(
-            final String name,
-            final MessageFactory messageFactory,
-            final BiFunction<String, MessageFactory, T> loggerSupplier) {
-
-        // Check arguments
-        requireNonNull(name, "name");
-        requireNonNull(messageFactory, "messageFactory");
-        requireNonNull(loggerSupplier, "loggerSupplier");
-
-        // Read lock fast path: See if logger already exists
-        T logger = getLogger(name, messageFactory);
-        if (logger != null) {
-            return logger;
-        }
-
-        // Write lock slow path: Insert the logger
-        writeLock.lock();
-        try {
-
-            // See if the logger is created by another thread in the meantime
-            final Map<MessageFactory, WeakReference<T>> 
loggerRefByMessageFactory =
-                    loggerRefByMessageFactoryByName.computeIfAbsent(name, 
this::createLoggerRefByMessageFactoryMap);
-            final WeakReference<T> loggerRef;
-            if ((loggerRef = loggerRefByMessageFactory.get(messageFactory)) != 
null
-                    && (logger = loggerRef.get()) != null) {
-                return logger;
-            }
-
-            // Create the logger
-            logger = loggerSupplier.apply(name, messageFactory);
-
-            // Report message factory mismatches, if there is any
-            final MessageFactory loggerMessageFactory = 
logger.getMessageFactory();
-            if (!loggerMessageFactory.equals(messageFactory)) {
-                StatusLogger.getLogger()
-                        .error(
-                                "Newly registered logger with name `{}` and 
message factory `{}`, is requested to be associated with a different message 
factory: `{}`.\n"
-                                        + "Effectively the message factory of 
the logger will be used and the other one will be ignored.\n"
-                                        + "This generally hints a problem at 
the logger context implementation.\n"
-                                        + "Please report this using the Log4j 
project issue tracker.",
-                                name,
-                                loggerMessageFactory,
-                                messageFactory);
-            }
-
-            // Insert the logger
-            loggerRefByMessageFactory.put(loggerMessageFactory, new 
WeakReference<>(logger));
-            return logger;
-        } finally {
-            writeLock.unlock();
-        }
-    }
-
     private Map<MessageFactory, WeakReference<T>> 
createLoggerRefByMessageFactoryMap(final String ignored) {
         return new WeakHashMap<>();
     }
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
index 3b6b5c2585..1748932083 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/package-info.java
@@ -19,7 +19,7 @@
  * API classes.
  */
 @Export
-@Version("2.25.0")
+@Version("2.24.1")
 package org.apache.logging.log4j.spi;
 
 import org.osgi.annotation.bundle.Export;
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 df8bb77481..88f66ac364 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
@@ -55,7 +55,6 @@ import org.apache.logging.log4j.spi.LoggerRegistry;
 import org.apache.logging.log4j.spi.Terminable;
 import org.apache.logging.log4j.spi.ThreadContextMapFactory;
 import org.apache.logging.log4j.util.PropertiesUtil;
-import org.jspecify.annotations.Nullable;
 
 /**
  * The LoggerContext is the anchor for the logging system. It maintains a list 
of all the loggers requested by
@@ -524,10 +523,16 @@ public class LoggerContext extends AbstractLifeCycle
      * @return a logger matching the given name and message factory
      */
     @Override
-    public Logger getLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public Logger getLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
-        return loggerRegistry.computeIfAbsent(name, effectiveMessageFactory, 
this::newInstance);
+        final Logger oldLogger = loggerRegistry.getLogger(name, 
effectiveMessageFactory);
+        if (oldLogger != null) {
+            return oldLogger;
+        }
+        final Logger newLogger = newInstance(name, effectiveMessageFactory);
+        loggerRegistry.putIfAbsent(name, effectiveMessageFactory, newLogger);
+        return loggerRegistry.getLogger(name, effectiveMessageFactory);
     }
 
     /**
@@ -558,7 +563,7 @@ public class LoggerContext extends AbstractLifeCycle
      * @return True if the Logger exists, false otherwise.
      */
     @Override
-    public boolean hasLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public boolean hasLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
         return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index beaf5134a0..83ed7d48f8 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -172,7 +172,7 @@ public abstract class AbstractAppender extends 
AbstractFilterable implements App
     private final boolean ignoreExceptions;
     private final Layout<? extends Serializable> layout;
 
-    private volatile ErrorHandler handler = new DefaultErrorHandler(this);
+    private ErrorHandler handler = new DefaultErrorHandler(this);
 
     @Override
     public boolean requiresLocation() {
@@ -316,6 +316,10 @@ public abstract class AbstractAppender extends 
AbstractFilterable implements App
             LOGGER.error("The handler cannot be set to null");
             return;
         }
+        if (isStarted()) {
+            LOGGER.error("The handler cannot be changed once the appender is 
started");
+            return;
+        }
         this.handler = handler;
     }
 
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
index a4e9858431..38c9c52b2e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpURLConnectionManager.java
@@ -100,8 +100,7 @@ public class HttpURLConnectionManager extends HttpManager {
                     header.getName(), 
header.evaluate(getConfiguration().getStrSubstitutor()));
         }
         if (sslConfiguration != null) {
-            ((HttpsURLConnection) urlConnection)
-                    
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
+            ((HttpsURLConnection) 
urlConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
         }
         if (isHttps && !verifyHostname) {
             ((HttpsURLConnection) 
urlConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
index 6eed83a54e..92bb0d5449 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/async/package-info.java
@@ -18,7 +18,7 @@
  * Provides Asynchronous Logger classes and interfaces for low-latency logging.
  */
 @Export
-@Version("2.24.1")
+@Version("2.24.0")
 package org.apache.logging.log4j.core.async;
 
 import org.osgi.annotation.bundle.Export;
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 3b301bde4d..4b160f98ef 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
@@ -17,12 +17,10 @@
 package org.apache.logging.log4j.core.config;
 
 import java.io.ByteArrayOutputStream;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Serializable;
 import java.lang.ref.WeakReference;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -281,10 +279,9 @@ public abstract class AbstractConfiguration extends 
AbstractFilterable implement
         if (configSource != null && (configSource.getFile() != null || 
configSource.getURL() != null)) {
             if (monitorIntervalSeconds > 0) {
                 watchManager.setIntervalSeconds(monitorIntervalSeconds);
-                File file = configSource.getFile();
-                if (file != null) {
-                    final Source cfgSource = new Source(file);
-                    final long lastModified = file.lastModified();
+                if (configSource.getFile() != null) {
+                    final Source cfgSource = new Source(configSource);
+                    final long lastModified = 
configSource.getFile().lastModified();
                     final ConfigurationFileWatcher watcher =
                             new ConfigurationFileWatcher(this, reconfigurable, 
listeners, lastModified);
                     watchManager.watch(cfgSource, watcher);
@@ -300,10 +297,8 @@ public abstract class AbstractConfiguration extends 
AbstractFilterable implement
     }
 
     private void monitorSource(final Reconfigurable reconfigurable, final 
ConfigurationSource configSource) {
-        URI uri = configSource.getURI();
-        if (uri != null && configSource.getLastModified() > 0) {
-            File file = configSource.getFile();
-            final Source cfgSource = file != null ? new Source(file) : new 
Source(uri);
+        if (configSource.getLastModified() > 0) {
+            final Source cfgSource = new Source(configSource);
             final Watcher watcher = WatcherFactory.getInstance(pluginPackages)
                     .newWatcher(cfgSource, this, reconfigurable, listeners, 
configSource.getLastModified());
             if (watcher != null) {
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
index d6143cdc15..ff443b08f3 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/ConfigurationSource.java
@@ -142,7 +142,7 @@ public class ConfigurationSource {
      * @param stream the input stream, the caller is responsible for closing 
this resource.
      * @throws IOException if an exception occurred reading from the specified 
stream
      */
-    public ConfigurationSource(InputStream stream) throws IOException {
+    public ConfigurationSource(final InputStream stream) throws IOException {
         this(toByteArray(stream), null, 0);
     }
 
@@ -298,13 +298,12 @@ public class ConfigurationSource {
 
     @Override
     public String toString() {
-        if (source != null) {
-            return source.getLocation();
+        if (isLocation()) {
+            return getLocation();
         }
         if (this == NULL_SOURCE) {
             return "NULL_SOURCE";
         }
-        byte[] data = this.data;
         final int length = data == null ? -1 : data.length;
         return "stream (" + length + " bytes, unknown location)";
     }
@@ -312,7 +311,7 @@ public class ConfigurationSource {
     /**
      * Loads the configuration from a URI.
      * @param configLocation A URI representing the location of the 
configuration.
-     * @return The ConfigurationSource for the configuration or {@code null}.
+     * @return The ConfigurationSource for the configuration.
      */
     public static /*@Nullable*/ ConfigurationSource fromUri(final URI 
configLocation) {
         final File configFile = FileUtils.fileFromUri(configLocation);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
index f129b80fe4..9c362ed045 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SmtpManager.java
@@ -308,8 +308,7 @@ public class SmtpManager extends MailManager {
             if (smtpProtocol.equals("smtps")) {
                 final SslConfiguration sslConfiguration = 
data.getSslConfiguration();
                 if (sslConfiguration != null) {
-                    final SSLSocketFactory sslSocketFactory =
-                            
sslConfiguration.getSslContext().getSocketFactory();
+                    final SSLSocketFactory sslSocketFactory = 
sslConfiguration.getSslSocketFactory();
                     properties.put(prefix + ".ssl.socketFactory", 
sslSocketFactory);
                     properties.setProperty(
                             prefix + ".ssl.checkserveridentity", 
Boolean.toString(sslConfiguration.isVerifyHostName()));
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
index 4f28e57502..8326f3ceeb 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/SslSocketManager.java
@@ -22,13 +22,7 @@ import java.io.Serializable;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Socket;
-import java.security.KeyStoreException;
-import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.Enumeration;
 import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 import org.apache.logging.log4j.core.Layout;
@@ -203,8 +197,6 @@ public class SslSocketManager extends TcpSocketManager {
             final Layout<? extends Serializable> layout,
             final int bufferSize,
             final SocketOptions socketOptions) {
-
-        // Check arguments
         if (Strings.isEmpty(host)) {
             throw new IllegalArgumentException("A host name is required");
         }
@@ -214,14 +206,7 @@ public class SslSocketManager extends TcpSocketManager {
         if (reconnectDelayMillis == 0) {
             reconnectDelayMillis = DEFAULT_RECONNECTION_DELAY_MILLIS;
         }
-
-        // Create an ID associated with the SSL configuration. This is 
necessary to make sure a new `name` is generated
-        // (and consequently a new connection pool is created) upon 
reconfiguration with a different configuration;
-        // e.g., change in the SSL certificate content, even though the 
certificate file locations are still the same.
-        // See #2767 and LOG4J2-2988 for details.
-        final String sslConfigId = createSslConfigurationId(sslConfig);
-        final String name = String.format("%s:%s:%d:%s", 
sslConfig.getProtocol(), host, port, sslConfigId);
-
+        final String name = "TLS:" + host + ':' + port;
         return (SslSocketManager) getManager(
                 name,
                 new SslFactoryData(
@@ -237,49 +222,6 @@ public class SslSocketManager extends TcpSocketManager {
                 FACTORY);
     }
 
-    /**
-     * Creates a unique identifier using the certificate issuers and serial 
numbers of the given SSL configuration.
-     *
-     * @param sslConfig an SSL configuration
-     * @return a unique identifier extracted from the given SSL configuration
-     */
-    private static String createSslConfigurationId(final SslConfiguration 
sslConfig) {
-        return String.valueOf(Stream.of(sslConfig.getKeyStoreConfig(), 
sslConfig.getTrustStoreConfig())
-                .flatMap(keyStoreConfig -> {
-                    final Enumeration<String> aliases;
-                    try {
-                        aliases = keyStoreConfig.getKeyStore().aliases();
-                    } catch (final KeyStoreException error) {
-                        LOGGER.error(
-                                "Failed reading the aliases for the key store 
located at `{}`",
-                                keyStoreConfig.getLocation(),
-                                error);
-                        return Stream.empty();
-                    }
-                    return 
Collections.list(aliases).stream().sorted().flatMap(alias -> {
-                        final X509Certificate certificate;
-                        try {
-                            certificate = (X509Certificate)
-                                    
keyStoreConfig.getKeyStore().getCertificate(alias);
-                        } catch (final KeyStoreException error) {
-                            LOGGER.error(
-                                    "Failed reading the certificate of alias 
`{}` for the key store located at `{}`",
-                                    alias,
-                                    keyStoreConfig.getLocation(),
-                                    error);
-                            return Stream.empty();
-                        }
-                        final String issuer =
-                                certificate.getIssuerX500Principal().getName();
-                        final String serialNumber =
-                                certificate.getSerialNumber().toString();
-                        return Stream.of(issuer, serialNumber);
-                    });
-                })
-                .collect(Collectors.toList())
-                .hashCode());
-    }
-
     @Override
     protected Socket createSocket(final InetSocketAddress socketAddress) 
throws IOException {
         final SSLSocketFactory socketFactory = 
createSslSocketFactory(sslConfig);
@@ -292,7 +234,7 @@ public class SslSocketManager extends TcpSocketManager {
         SSLSocketFactory socketFactory;
 
         if (sslConf != null) {
-            socketFactory = sslConf.getSslContext().getSocketFactory();
+            socketFactory = sslConf.getSslSocketFactory();
         } else {
             socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
         }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
index e6ba2a1366..7c5416210e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/UrlConnectionFactory.java
@@ -102,8 +102,7 @@ public class UrlConnectionFactory {
                 httpURLConnection.setIfModifiedSince(lastModifiedMillis);
             }
             if (url.getProtocol().equals(HTTPS) && sslConfiguration != null) {
-                ((HttpsURLConnection) httpURLConnection)
-                        
.setSSLSocketFactory(sslConfiguration.getSslContext().getSocketFactory());
+                ((HttpsURLConnection) 
httpURLConnection).setSSLSocketFactory(sslConfiguration.getSslSocketFactory());
                 if (!sslConfiguration.isVerifyHostName()) {
                     ((HttpsURLConnection) 
httpURLConnection).setHostnameVerifier(LaxHostnameVerifier.INSTANCE);
                 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
index a70b71edd3..ad928482d9 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/AbstractKeyStoreConfiguration.java
@@ -33,10 +33,9 @@ import org.apache.logging.log4j.core.util.NetUtils;
  */
 public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore> {
 
+    private final KeyStore keyStore;
     private final String keyStoreType;
 
-    private final transient KeyStore keyStore;
-
     public AbstractKeyStoreConfiguration(
             final String location, final PasswordProvider passwordProvider, 
final String keyStoreType)
             throws StoreConfigurationException {
@@ -115,7 +114,7 @@ public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore>
         }
     }
 
-    private static InputStream openInputStream(final String filePathOrUri) {
+    private InputStream openInputStream(final String filePathOrUri) {
         return 
ConfigurationSource.fromUri(NetUtils.toURI(filePathOrUri)).getInputStream();
     }
 
@@ -127,6 +126,7 @@ public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore>
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
+        result = prime * result + ((keyStore == null) ? 0 : 
keyStore.hashCode());
         result = prime * result + ((keyStoreType == null) ? 0 : 
keyStoreType.hashCode());
         return result;
     }
@@ -143,6 +143,9 @@ public class AbstractKeyStoreConfiguration extends 
StoreConfiguration<KeyStore>
             return false;
         }
         final AbstractKeyStoreConfiguration other = 
(AbstractKeyStoreConfiguration) obj;
+        if (!Objects.equals(keyStore, other.keyStore)) {
+            return false;
+        }
         if (!Objects.equals(keyStoreType, other.keyStoreType)) {
             return false;
         }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
index 205f7b0d9d..6e23d5bb40 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java
@@ -161,7 +161,7 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
      * Extension Reference Guide for information about these names.
      * @return a new KeyStoreConfiguration
      * @throws StoreConfigurationException Thrown if this call cannot load the 
KeyStore.
-     * @deprecated Use {@link #createKeyStoreConfiguration(String, char[], 
String, String, String, String)}
+     * @deprecated Use createKeyStoreConfiguration(String, char[], String, 
String)
      */
     @Deprecated
     public static KeyStoreConfiguration createKeyStoreConfiguration(
@@ -176,10 +176,6 @@ public class KeyStoreConfiguration extends 
AbstractKeyStoreConfiguration {
                 location, (password == null ? null : password.toCharArray()), 
keyStoreType, keyManagerFactoryAlgorithm);
     }
 
-    /**
-     * @deprecated Planned to be removed in the next major release
-     */
-    @Deprecated
     public KeyManagerFactory initKeyManagerFactory()
             throws NoSuchAlgorithmException, UnrecoverableKeyException, 
KeyStoreException {
         final KeyManagerFactory kmFactory = 
KeyManagerFactory.getInstance(this.keyManagerFactoryAlgorithm);
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
index ec37de3b9e..ca61176a30 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/PasswordProvider.java
@@ -26,7 +26,6 @@ package org.apache.logging.log4j.core.net.ssl;
  * is no longer needed.
  * </p>
  */
-@FunctionalInterface
 public interface PasswordProvider {
 
     /**
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
index cb24113bd9..68ee689b9e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
@@ -16,7 +16,10 @@
  */
 package org.apache.logging.log4j.core.net.ssl;
 
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
+import java.security.UnrecoverableKeyException;
 import java.util.Objects;
 import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
@@ -31,42 +34,29 @@ import 
org.apache.logging.log4j.core.config.plugins.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
 import org.apache.logging.log4j.status.StatusLogger;
-import org.jspecify.annotations.NullMarked;
-import org.jspecify.annotations.NullUnmarked;
-import org.jspecify.annotations.Nullable;
 
 /**
  *  SSL Configuration
  */
-@NullMarked
 @Plugin(name = "Ssl", category = Core.CATEGORY_NAME, printObject = true)
 public class SslConfiguration {
-
     private static final StatusLogger LOGGER = StatusLogger.getLogger();
-
-    private final String protocol;
-
-    private final boolean verifyHostName;
-
-    @Nullable
     private final KeyStoreConfiguration keyStoreConfig;
-
-    @Nullable
     private final TrustStoreConfiguration trustStoreConfig;
-
-    private final transient SSLContext sslContext;
+    private final SSLContext sslContext;
+    private final String protocol;
+    private final boolean verifyHostName;
 
     private SslConfiguration(
-            @Nullable final String protocol,
-            final boolean verifyHostName,
-            @Nullable final KeyStoreConfiguration keyStoreConfig,
-            @Nullable final TrustStoreConfiguration trustStoreConfig) {
+            final String protocol,
+            final KeyStoreConfiguration keyStoreConfig,
+            final TrustStoreConfiguration trustStoreConfig,
+            final boolean verifyHostName) {
         this.keyStoreConfig = keyStoreConfig;
         this.trustStoreConfig = trustStoreConfig;
-        final String effectiveProtocol = protocol == null ? 
SslConfigurationDefaults.PROTOCOL : protocol;
-        this.protocol = effectiveProtocol;
+        this.protocol = protocol == null ? SslConfigurationDefaults.PROTOCOL : 
protocol;
+        this.sslContext = this.createSslContext();
         this.verifyHostName = verifyHostName;
-        this.sslContext = createSslContext(effectiveProtocol, keyStoreConfig, 
trustStoreConfig);
     }
 
     /**
@@ -81,96 +71,157 @@ public class SslConfiguration {
         }
     }
 
-    /**
-     * Gets the SSL socket factory of the configured SSL context.
-     *
-     * @return the SSL socket factory of the configured SSL context
-     * @deprecated Use {@link SSLContext#getSocketFactory()} on {@link 
#getSslContext()}
-     */
-    @Deprecated
     public SSLSocketFactory getSslSocketFactory() {
         return sslContext.getSocketFactory();
     }
 
-    /**
-     * Gets the SSL server socket factory of the configured SSL context.
-     *
-     * @return the SSL server socket factory of the configured SSL context
-     * @deprecated Use {@link SSLContext#getServerSocketFactory()} on {@link 
#getSslContext()}
-     */
-    @Deprecated
     public SSLServerSocketFactory getSslServerSocketFactory() {
         return sslContext.getServerSocketFactory();
     }
 
-    private static SSLContext createDefaultSslContext(final String protocol) {
+    private SSLContext createSslContext() {
+        SSLContext context = null;
+
+        try {
+            context = createSslContextBasedOnConfiguration();
+            LOGGER.debug("Creating SSLContext with the given parameters");
+        } catch (final TrustStoreConfigurationException e) {
+            context = createSslContextWithTrustStoreFailure();
+        } catch (final KeyStoreConfigurationException e) {
+            context = createSslContextWithKeyStoreFailure();
+        }
+        return context;
+    }
+
+    private SSLContext createSslContextWithTrustStoreFailure() {
+        SSLContext context;
+
+        try {
+            context = createSslContextWithDefaultTrustManagerFactory();
+            LOGGER.debug("Creating SSLContext with default truststore");
+        } catch (final KeyStoreConfigurationException e) {
+            context = createDefaultSslContext();
+            LOGGER.debug("Creating SSLContext with default configuration");
+        }
+        return context;
+    }
+
+    private SSLContext createSslContextWithKeyStoreFailure() {
+        SSLContext context;
+
+        try {
+            context = createSslContextWithDefaultKeyManagerFactory();
+            LOGGER.debug("Creating SSLContext with default keystore");
+        } catch (final TrustStoreConfigurationException e) {
+            context = createDefaultSslContext();
+            LOGGER.debug("Creating SSLContext with default configuration");
+        }
+        return context;
+    }
+
+    private SSLContext createSslContextBasedOnConfiguration()
+            throws KeyStoreConfigurationException, 
TrustStoreConfigurationException {
+        return createSslContext(false, false);
+    }
+
+    private SSLContext createSslContextWithDefaultKeyManagerFactory() throws 
TrustStoreConfigurationException {
+        try {
+            return createSslContext(true, false);
+        } catch (final KeyStoreConfigurationException dummy) {
+            LOGGER.debug("Exception occurred while using default keystore. 
This should be a BUG");
+            return null;
+        }
+    }
+
+    private SSLContext createSslContextWithDefaultTrustManagerFactory() throws 
KeyStoreConfigurationException {
+        try {
+            return createSslContext(false, true);
+        } catch (final TrustStoreConfigurationException dummy) {
+            LOGGER.debug("Exception occurred while using default truststore. 
This should be a BUG");
+            return null;
+        }
+    }
+
+    private SSLContext createDefaultSslContext() {
         try {
             return SSLContext.getDefault();
-        } catch (final NoSuchAlgorithmException defaultContextError) {
-            LOGGER.error(
-                    "Failed to create an `SSLContext` using the default 
configuration, falling back to creating an empty one",
-                    defaultContextError);
-            try {
-                final SSLContext emptyContext = 
SSLContext.getInstance(protocol);
-                emptyContext.init(new KeyManager[0], new TrustManager[0], 
null);
-                return emptyContext;
-            } catch (final Exception emptyContextError) {
-                LOGGER.error("Failed to create an empty `SSLContext`", 
emptyContextError);
-                return null;
-            }
+        } catch (final NoSuchAlgorithmException e) {
+            LOGGER.error("Failed to create an SSLContext with default 
configuration", e);
+            return null;
         }
     }
 
-    private static SSLContext createSslContext(
-            final String protocol,
-            @Nullable final KeyStoreConfiguration keyStoreConfig,
-            @Nullable final TrustStoreConfiguration trustStoreConfig) {
+    private SSLContext createSslContext(
+            final boolean loadDefaultKeyManagerFactory, final boolean 
loadDefaultTrustManagerFactory)
+            throws KeyStoreConfigurationException, 
TrustStoreConfigurationException {
         try {
-            final SSLContext sslContext = SSLContext.getInstance(protocol);
-            final KeyManager[] keyManagers = loadKeyManagers(keyStoreConfig);
-            final TrustManager[] trustManagers = 
loadTrustManagers(trustStoreConfig);
-            sslContext.init(keyManagers, trustManagers, null);
-            return sslContext;
-        } catch (final Exception error) {
-            LOGGER.error(
-                    "Failed to create an `SSLContext` using the provided 
configuration, falling back to a default instance",
-                    error);
-            return createDefaultSslContext(protocol);
+            KeyManager[] kManagers = null;
+            TrustManager[] tManagers = null;
+
+            final SSLContext newSslContext = 
SSLContext.getInstance(this.protocol);
+            if (!loadDefaultKeyManagerFactory) {
+                final KeyManagerFactory kmFactory = loadKeyManagerFactory();
+                kManagers = kmFactory.getKeyManagers();
+            }
+            if (!loadDefaultTrustManagerFactory) {
+                final TrustManagerFactory tmFactory = 
loadTrustManagerFactory();
+                tManagers = tmFactory.getTrustManagers();
+            }
+
+            newSslContext.init(kManagers, tManagers, null);
+            return newSslContext;
+        } catch (final NoSuchAlgorithmException e) {
+            LOGGER.error("No Provider supports a TrustManagerFactorySpi 
implementation for the specified protocol", e);
+            throw new TrustStoreConfigurationException(e);
+        } catch (final KeyManagementException e) {
+            LOGGER.error("Failed to initialize the SSLContext", e);
+            throw new KeyStoreConfigurationException(e);
         }
     }
 
-    private static KeyManager[] loadKeyManagers(@Nullable final 
KeyStoreConfiguration config) throws Exception {
-        if (config == null) {
-            return new KeyManager[0];
+    private TrustManagerFactory loadTrustManagerFactory() throws 
TrustStoreConfigurationException {
+        if (trustStoreConfig == null) {
+            throw new TrustStoreConfigurationException(new Exception("The 
trustStoreConfiguration is null"));
         }
-        final KeyManagerFactory factory = 
KeyManagerFactory.getInstance(config.getKeyManagerFactoryAlgorithm());
-        final char[] password = config.getPasswordAsCharArray();
+
         try {
-            factory.init(config.getKeyStore(), password);
-        } finally {
-            config.clearSecrets();
+            return trustStoreConfig.initTrustManagerFactory();
+        } catch (final NoSuchAlgorithmException e) {
+            LOGGER.error("The specified algorithm is not available from the 
specified provider", e);
+            throw new TrustStoreConfigurationException(e);
+        } catch (final KeyStoreException e) {
+            LOGGER.error("Failed to initialize the TrustManagerFactory", e);
+            throw new TrustStoreConfigurationException(e);
         }
-        return factory.getKeyManagers();
     }
 
-    private static TrustManager[] loadTrustManagers(@Nullable final 
TrustStoreConfiguration config) throws Exception {
-        if (config == null) {
-            return new TrustManager[0];
+    private KeyManagerFactory loadKeyManagerFactory() throws 
KeyStoreConfigurationException {
+        if (keyStoreConfig == null) {
+            throw new KeyStoreConfigurationException(new Exception("The 
keyStoreConfiguration is null"));
+        }
+
+        try {
+            return keyStoreConfig.initKeyManagerFactory();
+        } catch (final NoSuchAlgorithmException e) {
+            LOGGER.error("The specified algorithm is not available from the 
specified provider", e);
+            throw new KeyStoreConfigurationException(e);
+        } catch (final KeyStoreException e) {
+            LOGGER.error("Failed to initialize the TrustManagerFactory", e);
+            throw new KeyStoreConfigurationException(e);
+        } catch (final UnrecoverableKeyException e) {
+            LOGGER.error("The key cannot be recovered (e.g. the given password 
is wrong)", e);
+            throw new KeyStoreConfigurationException(e);
         }
-        final TrustManagerFactory factory = 
TrustManagerFactory.getInstance(config.getTrustManagerFactoryAlgorithm());
-        factory.init(config.getKeyStore());
-        return factory.getTrustManagers();
     }
 
     /**
      * Creates an SslConfiguration from a KeyStoreConfiguration and a 
TrustStoreConfiguration.
      *
-     * @param protocol         The protocol, see <a 
href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext";>SSLContext
 Algorithms</a>
-     * @param keyStoreConfig   The KeyStoreConfiguration.
+     * @param protocol The protocol, see <a 
href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#SSLContext";>SSLContext
 Algorithms</a>
+     * @param keyStoreConfig The KeyStoreConfiguration.
      * @param trustStoreConfig The TrustStoreConfiguration.
      * @return a new SslConfiguration
      */
-    @NullUnmarked
     @PluginFactory
     public static SslConfiguration createSSLConfiguration(
             // @formatter:off
@@ -178,7 +229,7 @@ public class SslConfiguration {
             @PluginElement("KeyStore") final KeyStoreConfiguration 
keyStoreConfig,
             @PluginElement("TrustStore") final TrustStoreConfiguration 
trustStoreConfig) {
         // @formatter:on
-        return new SslConfiguration(protocol, false, keyStoreConfig, 
trustStoreConfig);
+        return new SslConfiguration(protocol, keyStoreConfig, 
trustStoreConfig, false);
     }
 
     /**
@@ -191,7 +242,6 @@ public class SslConfiguration {
      * @return a new SslConfiguration
      * @since 2.12
      */
-    @NullUnmarked
     public static SslConfiguration createSSLConfiguration(
             // @formatter:off
             @PluginAttribute("protocol") final String protocol,
@@ -199,7 +249,7 @@ public class SslConfiguration {
             @PluginElement("TrustStore") final TrustStoreConfiguration 
trustStoreConfig,
             @PluginAttribute("verifyHostName") final boolean verifyHostName) {
         // @formatter:on
-        return new SslConfiguration(protocol, verifyHostName, keyStoreConfig, 
trustStoreConfig);
+        return new SslConfiguration(protocol, keyStoreConfig, 
trustStoreConfig, verifyHostName);
     }
 
     @Override
@@ -219,13 +269,13 @@ public class SslConfiguration {
             return false;
         }
         final SslConfiguration other = (SslConfiguration) obj;
-        if (!Objects.equals(protocol, other.protocol)) {
+        if (!Objects.equals(keyStoreConfig, other.keyStoreConfig)) {
             return false;
         }
-        if (!Objects.equals(verifyHostName, other.verifyHostName)) {
+        if (!Objects.equals(protocol, other.protocol)) {
             return false;
         }
-        if (!Objects.equals(keyStoreConfig, other.keyStoreConfig)) {
+        if (!Objects.equals(sslContext, other.sslContext)) {
             return false;
         }
         if (!Objects.equals(trustStoreConfig, other.trustStoreConfig)) {
@@ -234,14 +284,6 @@ public class SslConfiguration {
         return true;
     }
 
-    public String getProtocol() {
-        return protocol;
-    }
-
-    public boolean isVerifyHostName() {
-        return verifyHostName;
-    }
-
     public KeyStoreConfiguration getKeyStoreConfig() {
         return keyStoreConfig;
     }
@@ -253,4 +295,12 @@ public class SslConfiguration {
     public SSLContext getSslContext() {
         return sslContext;
     }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public boolean isVerifyHostName() {
+        return verifyHostName;
+    }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
index 2da16b886d..6c09ad2c09 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfigurationFactory.java
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.util.Strings;
 public class SslConfigurationFactory {
 
     private static final Logger LOGGER = StatusLogger.getLogger();
+    private static final SslConfiguration sslConfiguration = 
createSslConfiguration(PropertiesUtil.getProperties());
 
     private static final String trustStorelocation = 
"log4j2.trustStoreLocation";
     private static final String trustStorePassword = 
"log4j2.trustStorePassword";
@@ -110,6 +111,6 @@ public class SslConfigurationFactory {
     }
 
     public static SslConfiguration getSslConfiguration() {
-        return createSslConfiguration(PropertiesUtil.getProperties());
+        return sslConfiguration;
     }
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
index 0c4393bc19..e50a4a377e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/StoreConfiguration.java
@@ -58,7 +58,7 @@ public class StoreConfiguration<T> {
      */
     public void clearSecrets() {
         this.location = null;
-        this.passwordProvider = new MemoryPasswordProvider(new char[0]);
+        this.passwordProvider = null;
     }
 
     public String getLocation() {
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
index 5b27b883b0..6dc212303d 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java
@@ -152,7 +152,7 @@ public class TrustStoreConfiguration extends 
AbstractKeyStoreConfiguration {
      * Secure Socket Extension Reference Guide for information these names.
      * @return a new TrustStoreConfiguration
      * @throws StoreConfigurationException Thrown if this instance cannot load 
the KeyStore.
-     * @deprecated Use {@link #createKeyStoreConfiguration(String, char[], 
String, String, String, String)}
+     * @deprecated Use createKeyStoreConfiguration(String, char[], String, 
String)
      */
     @Deprecated
     public static TrustStoreConfiguration createKeyStoreConfiguration(
@@ -172,10 +172,6 @@ public class TrustStoreConfiguration extends 
AbstractKeyStoreConfiguration {
                 trustManagerFactoryAlgorithm);
     }
 
-    /**
-     * @deprecated Planned to be removed in the next major release
-     */
-    @Deprecated
     public TrustManagerFactory initTrustManagerFactory() throws 
NoSuchAlgorithmException, KeyStoreException {
         final TrustManagerFactory tmFactory = 
TrustManagerFactory.getInstance(this.trustManagerFactoryAlgorithm);
         tmFactory.init(this.getKeyStore());
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
index 7f7b26c282..db4860c1ff 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/package-info.java
@@ -18,7 +18,7 @@
  * Log4j 2 SSL support
  */
 @Export
-@Version("2.20.3")
+@Version("2.20.2")
 package org.apache.logging.log4j.core.net.ssl;
 
 import org.osgi.annotation.bundle.Export;
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
index 00552976b7..7c02b12fe6 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/package-info.java
@@ -18,7 +18,7 @@
  * Implementation of Log4j 2.
  */
 @Export
-@Version("2.24.2")
+@Version("2.24.1")
 package org.apache.logging.log4j.core;
 
 import org.osgi.annotation.bundle.Export;
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 64ee6be359..b4e035c9fb 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
@@ -23,7 +23,6 @@ import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.LoaderUtil;
 import org.apache.logging.log4j.util.PropertiesUtil;
-import org.jspecify.annotations.Nullable;
 
 /**
  * Load resources (or images) from various sources.
@@ -85,9 +84,9 @@ public final class Loader {
      * </ol>
      * @param resource The resource to load.
      * @param defaultLoader The default ClassLoader.
-     * @return A URL to the resource or {@code null}.
+     * @return A URL to the resource.
      */
-    public static @Nullable URL getResource(final String resource, final 
ClassLoader defaultLoader) {
+    public static URL getResource(final String resource, final ClassLoader 
defaultLoader) {
         try {
             ClassLoader classLoader = getThreadContextClassLoader();
             if (classLoader != null) {
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
index 5a79ab8b9a..580d3b73d4 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Source.java
@@ -16,8 +16,6 @@
  */
 package org.apache.logging.log4j.core.util;
 
-import static java.util.Objects.requireNonNull;
-
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import java.io.File;
 import java.io.IOException;
@@ -32,13 +30,10 @@ import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.config.ConfigurationSource;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.Strings;
-import org.jspecify.annotations.NullMarked;
-import org.jspecify.annotations.Nullable;
 
 /**
  * Represents the source for the logging configuration as an immutable object.
  */
-@NullMarked
 public class Source {
     private static final Logger LOGGER = StatusLogger.getLogger();
 
@@ -50,9 +45,9 @@ public class Source {
         }
     }
 
-    private static @Nullable File toFile(Path path) {
+    private static File toFile(final Path path) {
         try {
-            return requireNonNull(path, "path").toFile();
+            return Objects.requireNonNull(path, "path").toFile();
         } catch (final UnsupportedOperationException e) {
             return null;
         }
@@ -62,9 +57,9 @@ public class Source {
     @SuppressFBWarnings(
             value = "PATH_TRAVERSAL_IN",
             justification = "The URI should be specified in a configuration 
file.")
-    private static @Nullable File toFile(URI uri) {
+    private static File toFile(final URI uri) {
         try {
-            final String scheme = requireNonNull(uri, "uri").getScheme();
+            final String scheme = Objects.requireNonNull(uri, 
"uri").getScheme();
             if (Strings.isBlank(scheme) || scheme.equals("file")) {
                 return new File(uri.getPath());
             } else {
@@ -72,20 +67,20 @@ public class Source {
                 return null;
             }
         } catch (final Exception e) {
-            LOGGER.debug("uri is malformed: " + uri);
+            LOGGER.debug("uri is malformed: " + uri.toString());
             return null;
         }
     }
 
     private static URI toURI(final URL url) {
         try {
-            return requireNonNull(url, "url").toURI();
+            return Objects.requireNonNull(url, "url").toURI();
         } catch (final URISyntaxException e) {
             throw new IllegalArgumentException(e);
         }
     }
 
-    private final @Nullable File file;
+    private final File file;
     private final URI uri;
     private final String location;
 
@@ -93,23 +88,21 @@ public class Source {
      * Constructs a Source from a ConfigurationSource.
      *
      * @param source The ConfigurationSource.
-     * @throws NullPointerException if {@code source} is {@code null}.
      */
     public Source(final ConfigurationSource source) {
         this.file = source.getFile();
-        this.uri = requireNonNull(source.getURI());
-        this.location = requireNonNull(source.getLocation());
+        this.uri = source.getURI();
+        this.location = source.getLocation();
     }
 
     /**
      * Constructs a new {@code Source} with the specified file.
      * file.
      *
-     * @param file the file where the input stream originated.
-     * @throws NullPointerException if {@code file} is {@code null}.
+     * @param file the file where the input stream originated
      */
     public Source(final File file) {
-        this.file = requireNonNull(file, "file");
+        this.file = Objects.requireNonNull(file, "file");
         this.location = normalize(file);
         this.uri = file.toURI();
     }
@@ -118,10 +111,9 @@ public class Source {
      * Constructs a new {@code Source} from the specified Path.
      *
      * @param path the Path where the input stream originated
-     * @throws NullPointerException if {@code path} is {@code null}.
      */
     public Source(final Path path) {
-        final Path normPath = requireNonNull(path, "path").normalize();
+        final Path normPath = Objects.requireNonNull(path, "path").normalize();
         this.file = toFile(normPath);
         this.uri = normPath.toUri();
         this.location = normPath.toString();
@@ -131,10 +123,9 @@ public class Source {
      * Constructs a new {@code Source} from the specified URI.
      *
      * @param uri the URI where the input stream originated
-     * @throws NullPointerException if {@code uri} is {@code null}.
      */
     public Source(final URI uri) {
-        final URI normUri = requireNonNull(uri, "uri").normalize();
+        final URI normUri = Objects.requireNonNull(uri, "uri").normalize();
         this.uri = normUri;
         this.location = normUri.toString();
         this.file = toFile(normUri);
@@ -144,12 +135,11 @@ public class Source {
      * Constructs a new {@code Source} from the specified URI.
      *
      * @param uri the URI where the input stream originated
-     * @param ignored Not used.
+     * @param lastModified Not used.
      * @deprecated Use {@link Source#Source(URI)}.
-     * @throws NullPointerException if {@code uri} is {@code null}.
      */
     @Deprecated
-    public Source(URI uri, long ignored) {
+    public Source(final URI uri, final long lastModified) {
         this(uri);
     }
 
@@ -157,7 +147,6 @@ public class Source {
      * Constructs a new {@code Source} from the specified URL.
      *
      * @param url the URL where the input stream originated
-     * @throws NullPointerException if this URL is {@code null}.
      * @throws IllegalArgumentException if this URL is not formatted strictly 
according to RFC2396 and cannot be
      *         converted to a URI.
      */
@@ -185,7 +174,7 @@ public class Source {
      *
      * @return the configuration source file, or {@code null}
      */
-    public @Nullable File getFile() {
+    public File getFile() {
         return file;
     }
 
@@ -208,7 +197,7 @@ public class Source {
             value = "PATH_TRAVERSAL_IN",
             justification = "The `file`, `uri` and `location` fields come from 
Log4j properties.")
     public Path getPath() {
-        return file != null ? file.toPath() : Paths.get(uri);
+        return file != null ? file.toPath() : uri != null ? Paths.get(uri) : 
Paths.get(location);
     }
 
     /**
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
index 96541cd57c..f444c25350 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FastDatePrinter.java
@@ -457,7 +457,7 @@ public class FastDatePrinter implements DatePrinter, 
Serializable {
     }
 
     /**
-     * Creation method for new calendar instances.
+     * Creation method for new calender instances.
      * @return a new Calendar instance.
      */
     private Calendar newCalendar() {
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/package-info.java 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/package-info.java
index 06e847dcfe..73ad2271ba 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/package-info.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/package-info.java
@@ -18,7 +18,7 @@
  * Log4j 2 helper classes.
  */
 @Export
-@Version("2.24.2")
+@Version("2.24.1")
 package org.apache.logging.log4j.core.util;
 
 import org.osgi.annotation.bundle.Export;
diff --git 
a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
 
b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
index ab1963ea23..afa401341c 100644
--- 
a/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
+++ 
b/log4j-jakarta-smtp/src/main/java/org/apache/logging/log4j/smtp/SmtpManager.java
@@ -262,8 +262,7 @@ public class SmtpManager extends MailManager {
             if (smtpProtocol.equals("smtps")) {
                 final SslConfiguration sslConfiguration = 
data.getSslConfiguration();
                 if (sslConfiguration != null) {
-                    final SSLSocketFactory sslSocketFactory =
-                            
sslConfiguration.getSslContext().getSocketFactory();
+                    final SSLSocketFactory sslSocketFactory = 
sslConfiguration.getSslSocketFactory();
                     properties.put(prefix + ".ssl.socketFactory", 
sslSocketFactory);
                     properties.setProperty(
                             prefix + ".ssl.checkserveridentity", 
Boolean.toString(sslConfiguration.isVerifyHostName()));
diff --git 
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
 
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
index 5d25ff6d89..46fb56f3de 100644
--- 
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
+++ 
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/Log4jTaglibLoggerContext.java
@@ -28,8 +28,6 @@ import 
org.apache.logging.log4j.message.ParameterizedMessageFactory;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerRegistry;
-import org.jspecify.annotations.NullMarked;
-import org.jspecify.annotations.Nullable;
 
 /**
  * This bridge between the tag library and the Log4j API ensures that 
instances of {@link Log4jTaglibLogger} are
@@ -37,7 +35,6 @@ import org.jspecify.annotations.Nullable;
  *
  * @since 2.0
  */
-@NullMarked
 final class Log4jTaglibLoggerContext implements LoggerContext {
 
     private static final ReadWriteLock LOCK = new ReentrantReadWriteLock();
@@ -70,13 +67,19 @@ final class Log4jTaglibLoggerContext implements 
LoggerContext {
     }
 
     @Override
-    public Log4jTaglibLogger getLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
+    public Log4jTaglibLogger getLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
-        return loggerRegistry.computeIfAbsent(name, effectiveMessageFactory, 
this::createLogger);
+        final Log4jTaglibLogger oldLogger = loggerRegistry.getLogger(name, 
effectiveMessageFactory);
+        if (oldLogger != null) {
+            return oldLogger;
+        }
+        final Log4jTaglibLogger newLogger = createLogger(name, 
effectiveMessageFactory);
+        loggerRegistry.putIfAbsent(name, effectiveMessageFactory, newLogger);
+        return loggerRegistry.getLogger(name, effectiveMessageFactory);
     }
 
-    private Log4jTaglibLogger createLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
+    private Log4jTaglibLogger createLogger(final String name, final 
MessageFactory messageFactory) {
         final LoggerContext loggerContext = LogManager.getContext(false);
         final ExtendedLogger delegateLogger = loggerContext.getLogger(name, 
messageFactory);
         return new Log4jTaglibLogger(delegateLogger, name, 
delegateLogger.getMessageFactory());
@@ -88,7 +91,7 @@ final class Log4jTaglibLoggerContext implements LoggerContext 
{
     }
 
     @Override
-    public boolean hasLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public boolean hasLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
         return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git 
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java 
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
index 9f8d273e7d..ac85ecafea 100644
--- 
a/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
+++ 
b/log4j-taglib/src/main/java/org/apache/logging/log4j/taglib/package-info.java
@@ -20,7 +20,7 @@
  * @since 2.0
  */
 @Export
-@Version("2.25.0")
+@Version("2.24.1")
 package org.apache.logging.log4j.taglib;
 
 import org.osgi.annotation.bundle.Export;
diff --git 
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
 
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
index 9f92dca493..ae6697fd98 100644
--- 
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
+++ 
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/JULLoggerContext.java
@@ -22,7 +22,6 @@ import 
org.apache.logging.log4j.message.ParameterizedMessageFactory;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerRegistry;
-import org.jspecify.annotations.Nullable;
 
 /**
  * Implementation of Log4j {@link LoggerContext} SPI.
@@ -49,13 +48,19 @@ class JULLoggerContext implements LoggerContext {
     }
 
     @Override
-    public ExtendedLogger getLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
+    public ExtendedLogger getLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
-        return loggerRegistry.computeIfAbsent(name, effectiveMessageFactory, 
JULLoggerContext::createLogger);
+        final ExtendedLogger oldLogger = loggerRegistry.getLogger(name, 
effectiveMessageFactory);
+        if (oldLogger != null) {
+            return oldLogger;
+        }
+        final ExtendedLogger newLogger = createLogger(name, 
effectiveMessageFactory);
+        loggerRegistry.putIfAbsent(name, effectiveMessageFactory, newLogger);
+        return loggerRegistry.getLogger(name, effectiveMessageFactory);
     }
 
-    private static ExtendedLogger createLogger(final String name, @Nullable 
final MessageFactory messageFactory) {
+    private static ExtendedLogger createLogger(final String name, final 
MessageFactory messageFactory) {
         final Logger logger = Logger.getLogger(name);
         return new JULLogger(name, messageFactory, logger);
     }
@@ -66,7 +71,7 @@ class JULLoggerContext implements LoggerContext {
     }
 
     @Override
-    public boolean hasLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public boolean hasLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
         return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git 
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java 
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
index 68812bb248..8308d5c2fa 100644
--- 
a/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
+++ 
b/log4j-to-jul/src/main/java/org/apache/logging/log4j/tojul/package-info.java
@@ -21,7 +21,7 @@
  * @author <a href="http://www.vorburger.ch";>Michael Vorburger.ch</a> for 
Google
  */
 @Export
-@Version("2.25.0")
+@Version("2.24.1")
 package org.apache.logging.log4j.tojul;
 
 import org.osgi.annotation.bundle.Export;
diff --git 
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java 
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
index ba2a1d4818..407a9636f0 100644
--- 
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
+++ 
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/SLF4JLoggerContext.java
@@ -21,7 +21,6 @@ import 
org.apache.logging.log4j.message.ParameterizedMessageFactory;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerRegistry;
-import org.jspecify.annotations.Nullable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -42,13 +41,19 @@ public class SLF4JLoggerContext implements LoggerContext {
     }
 
     @Override
-    public ExtendedLogger getLogger(final String name, @Nullable final 
MessageFactory messageFactory) {
+    public ExtendedLogger getLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
-        return loggerRegistry.computeIfAbsent(name, effectiveMessageFactory, 
SLF4JLoggerContext::createLogger);
+        final ExtendedLogger oldLogger = loggerRegistry.getLogger(name, 
effectiveMessageFactory);
+        if (oldLogger != null) {
+            return oldLogger;
+        }
+        final ExtendedLogger newLogger = createLogger(name, 
effectiveMessageFactory);
+        loggerRegistry.putIfAbsent(name, effectiveMessageFactory, newLogger);
+        return loggerRegistry.getLogger(name, effectiveMessageFactory);
     }
 
-    private static ExtendedLogger createLogger(final String name, @Nullable 
final MessageFactory messageFactory) {
+    private static ExtendedLogger createLogger(final String name, final 
MessageFactory messageFactory) {
         final Logger logger = LoggerFactory.getLogger(name);
         return new SLF4JLogger(name, messageFactory, logger);
     }
@@ -59,7 +64,7 @@ public class SLF4JLoggerContext implements LoggerContext {
     }
 
     @Override
-    public boolean hasLogger(final String name, @Nullable final MessageFactory 
messageFactory) {
+    public boolean hasLogger(final String name, final MessageFactory 
messageFactory) {
         final MessageFactory effectiveMessageFactory =
                 messageFactory != null ? messageFactory : 
DEFAULT_MESSAGE_FACTORY;
         return loggerRegistry.hasLogger(name, effectiveMessageFactory);
diff --git 
a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java 
b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
index 8e6a1c3ac8..12e4bedba2 100644
--- a/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
+++ b/log4j-to-slf4j/src/main/java/org/apache/logging/slf4j/package-info.java
@@ -18,7 +18,7 @@
  * SLF4J support.
  */
 @Export
-@Version("2.25.0")
+@Version("2.24.1")
 package org.apache.logging.slf4j;
 
 import org.osgi.annotation.bundle.Export;

Reply via email to