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); } }