static Provider selectProvider()

in log4j-api/src/main/java/org/apache/logging/log4j/util/ProviderUtil.java [180:263]


    static Provider selectProvider(
            final PropertiesUtil properties, final Collection<Provider> providers, final Logger statusLogger) {
        Provider selected = null;
        // 1. Select provider using "log4j.provider" property
        final String providerClass = properties.getStringProperty(PROVIDER_PROPERTY_NAME);
        if (providerClass != null) {
            if (SimpleProvider.class.getName().equals(providerClass)) {
                selected = new SimpleProvider();
            } else {
                try {
                    selected = LoaderUtil.newInstanceOf(providerClass);
                } catch (final Exception e) {
                    statusLogger.error(
                            "Unable to create provider {}.\nFalling back to default selection process.", PROVIDER, e);
                }
            }
        }
        // 2. Use deprecated "log4j2.loggerContextFactory" property to choose the provider
        final String factoryClassName = properties.getStringProperty(LogManager.FACTORY_PROPERTY_NAME);
        if (factoryClassName != null) {
            if (selected != null) {
                statusLogger.warn(
                        "Ignoring {} system property, since {} was set.",
                        LogManager.FACTORY_PROPERTY_NAME,
                        PROVIDER_PROPERTY_NAME);
                // 2a. Scan the known providers for one matching the logger context factory class name.
            } else {
                statusLogger.warn(
                        "Usage of the {} property is deprecated. Use the {} property instead.",
                        LogManager.FACTORY_PROPERTY_NAME,
                        PROVIDER_PROPERTY_NAME);
                for (final Provider provider : providers) {
                    if (factoryClassName.equals(provider.getClassName())) {
                        selected = provider;
                        break;
                    }
                }
            }
            // 2b. Instantiate
            if (selected == null) {
                statusLogger.warn(
                        "No provider found using {} as logger context factory. The factory will be instantiated directly.",
                        factoryClassName);
                try {
                    final Class<?> clazz = LoaderUtil.loadClass(factoryClassName);
                    if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
                        selected = new Provider(null, Strings.EMPTY, clazz.asSubclass(LoggerContextFactory.class));
                    } else {
                        statusLogger.error(
                                "Class {} specified in the {} system property does not extend {}",
                                factoryClassName,
                                LogManager.FACTORY_PROPERTY_NAME,
                                LoggerContextFactory.class.getName());
                    }
                } catch (final Exception e) {
                    statusLogger.error(
                            "Unable to create class {} specified in the {} system property",
                            factoryClassName,
                            LogManager.FACTORY_PROPERTY_NAME,
                            e);
                }
            }
        }
        // 3. Select a provider automatically.
        if (selected == null) {
            final Comparator<Provider> comparator = Comparator.comparing(Provider::getPriority);
            switch (providers.size()) {
                case 0:
                    statusLogger.error("Log4j API could not find a logging provider.");
                    break;
                case 1:
                    break;
                default:
                    statusLogger.warn(providers.stream()
                            .sorted(comparator)
                            .map(Provider::toString)
                            .collect(Collectors.joining("\n", "Log4j API found multiple logging providers:\n", "")));
                    break;
            }
            selected = providers.stream().max(comparator).orElseGet(SimpleProvider::new);
        }
        statusLogger.info("Using provider:\n{}", selected);
        return selected;
    }