This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch fix/main/recycler-factory-init in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 2415a42f5cc30768464345bd7e80ca875f03e393 Author: Volkan Yazıcı <vol...@yazi.ci> AuthorDate: Wed May 15 16:07:12 2024 +0200 Fix recycler factory initialization --- .../logging/log4j/core/impl/CoreDefaultBundle.java | 68 +++++++++++++++++----- 1 file changed, 52 insertions(+), 16 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..010cfe9b40 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,58 @@ 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) { + @Nullable final RecyclerFactory factory = matchingProvider.createForEnvironment(environment); + if (factory != null) { + return factory; + } else { + statusLogger.error( + "Configured recycler factory provider `{}` is not applicable for the current environment! Available recycler factory providers: {}. Will choose the first one available for the current environment.", + providerName, + providerNames); + } + } 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)) + .filter(Objects::nonNull) + .findFirst() + .orElseThrow(() -> new IllegalStateException( + "None of the available recycler factory providers are found to be available for the current environment: " + + providerNames)); } @SingletonFactory