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

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


The following commit(s) were added to refs/heads/main by this push:
     new cfedc22a23 Fix recycler factory initialization (#2583)
cfedc22a23 is described below

commit cfedc22a239b3cc8c34a30a3ebbd20da9a86b959
Author: Volkan Yazıcı <vol...@yazi.ci>
AuthorDate: Tue May 21 13:19:09 2024 +0200

    Fix recycler factory initialization (#2583)
---
 .../logging/log4j/core/impl/CoreDefaultBundle.java | 59 ++++++++++++++++------
 .../kit/recycler/RecyclerFactoryProvider.java      |  8 +--
 .../internal/QueueingRecyclerFactoryProvider.java  |  1 -
 .../recycler/internal/RecyclerFactoryTestUtil.java |  6 +--
 4 files changed, 47 insertions(+), 27 deletions(-)

diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreDefaultBundle.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreDefaultBundle.java
index 4e9e2f47e1..32718edf5e 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreDefaultBundle.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreDefaultBundle.java
@@ -17,11 +17,12 @@
 package org.apache.logging.log4j.core.impl;
 
 import java.util.Comparator;
+import java.util.List;
 import java.util.Map;
-import java.util.Optional;
+import java.util.Objects;
 import java.util.ServiceLoader;
 import java.util.function.Supplier;
-import java.util.stream.Stream;
+import java.util.stream.Collectors;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.async.AsyncQueueFullPolicy;
@@ -62,6 +63,7 @@ import org.apache.logging.log4j.spi.LoggerContextFactory;
 import org.apache.logging.log4j.spi.Provider;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.ServiceLoaderUtil;
+import org.jspecify.annotations.Nullable;
 
 /**
  * Provides instance binding defaults.
@@ -103,24 +105,49 @@ public final class CoreDefaultBundle {
 
     @SingletonFactory
     @ConditionalOnMissingBinding
-    public RecyclerFactoryProvider defaultRecyclerFactoryProvider(
+    public RecyclerFactory defaultRecyclerFactory(
             final PropertyEnvironment environment,
             final ClassLoader loader,
             final @Named("StatusLogger") org.apache.logging.log4j.Logger 
statusLogger) {
-        final String factory = 
environment.getProperty(RecyclerProperties.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);
+        // Collect providers
+        @Nullable
+        final String providerName =
+                environment.getProperty(RecyclerProperties.class).factory();
+        final List<RecyclerFactoryProvider> providers = 
ServiceLoaderUtil.safeStream(
+                        RecyclerFactoryProvider.class,
+                        ServiceLoader.load(RecyclerFactoryProvider.class, 
loader),
+                        statusLogger)
+                
.sorted(Comparator.comparing(RecyclerFactoryProvider::getOrder))
+                .toList();
+        final String providerNames = providers.stream()
+                .map(provider -> "`" + provider.getName() + "`")
+                .collect(Collectors.joining(", "));
+
+        // Try to create the configured provider
+        if (providerName != null) {
+            @Nullable
+            final RecyclerFactoryProvider matchingProvider = providers.stream()
+                    .filter(provider -> 
provider.getName().equals(providerName))
+                    .findFirst()
+                    .orElse(null);
+            if (matchingProvider != null) {
+                return matchingProvider.createForEnvironment(environment);
+            } else {
+                statusLogger.error(
+                        "Configured recycler factory provider `{}` is not 
found! Available recycler factory providers: {}. Will choose the first one 
available for the current environment.",
+                        providerName,
+                        providerNames);
+            }
+        }
+
+        // Fallback to the first available provider
+        return providers.stream()
+                .map(provider -> provider.createForEnvironment(environment))
+                .findFirst()
+                .orElseThrow(() -> new IllegalStateException(
+                        "None of the available recycler factory providers are 
found to be available for the current environment: "
+                                + providerNames));
     }
 
     @SingletonFactory
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 26ebd5900e..4512c90e1a 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
@@ -16,7 +16,6 @@
  */
 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;
 
@@ -51,14 +50,9 @@ public interface RecyclerFactoryProvider {
 
     /**
      * Creates a recycler factory for the provided environment.
-     * <p>
-     * The return value can be null indicating that the recycler factory is 
not available for the provided environment.
-     * For instance, the provider of a {@link ThreadLocal}-based recycler 
factory can return null if the environment is of a web application.
-     * </p>
      *
      * @param environment an environment
-     * @return either a recycler factory instance, or null, if the associated 
recycler factory is not available for the given environment
+     * @return a recycler factory instance for the given environment
      */
-    @Nullable
     RecyclerFactory createForEnvironment(PropertyEnvironment environment);
 }
diff --git 
a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/QueueingRecyclerFactoryProvider.java
 
b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/QueueingRecyclerFactoryProvider.java
index e124575db3..08fe068778 100644
--- 
a/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/QueueingRecyclerFactoryProvider.java
+++ 
b/log4j-kit/src/main/java/org/apache/logging/log4j/kit/recycler/internal/QueueingRecyclerFactoryProvider.java
@@ -49,7 +49,6 @@ public final class QueueingRecyclerFactoryProvider implements 
RecyclerFactoryPro
     @Override
     public RecyclerFactory createForEnvironment(final PropertyEnvironment 
environment) {
         requireNonNull(environment, "environment");
-
         final int capacity = 
environment.getProperty(RecyclerProperties.class).capacity();
         return new QueueingRecyclerFactory(capacity);
     }
diff --git 
a/log4j-kit/src/test/java/org/apache/logging/log4j/kit/recycler/internal/RecyclerFactoryTestUtil.java
 
b/log4j-kit/src/test/java/org/apache/logging/log4j/kit/recycler/internal/RecyclerFactoryTestUtil.java
index 98b00bf37b..985f525127 100644
--- 
a/log4j-kit/src/test/java/org/apache/logging/log4j/kit/recycler/internal/RecyclerFactoryTestUtil.java
+++ 
b/log4j-kit/src/test/java/org/apache/logging/log4j/kit/recycler/internal/RecyclerFactoryTestUtil.java
@@ -37,15 +37,15 @@ final class RecyclerFactoryTestUtil {
         if (capacity != null) {
             properties.put("recycler.capacity", capacity.toString());
         }
-        final PropertyEnvironment env = new 
TestPropertyEnvironment(properties);
+        final PropertyEnvironment environment = new 
TestPropertyEnvironment(properties);
         return ServiceLoaderUtil.safeStream(
                         RecyclerFactoryProvider.class,
                         ServiceLoader.load(
                                 RecyclerFactoryProvider.class, 
RecyclerFactoryTestUtil.class.getClassLoader()),
                         StatusLogger.getLogger())
-                .filter(p -> factory.equals(p.getName()))
+                .filter(factoryProvider -> 
factory.equals(factoryProvider.getName()))
                 .findFirst()
-                .map(p -> p.createForEnvironment(env))
+                .map(factoryProvider -> 
factoryProvider.createForEnvironment(environment))
                 .orElse(null);
     }
 }

Reply via email to