ppkarwasz commented on a change in pull request #804:
URL: https://github.com/apache/logging-log4j2/pull/804#discussion_r830288798
##########
File path:
log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
##########
@@ -60,43 +80,48 @@ private ServiceLoaderUtil() {
* @param serviceType The class of the service.
* @return A service of the given type or {@code null} if none is
available.
*/
- public static <T> T getService(final Class<T> serviceType) {
+ public static <T> Optional<T> getService(final Class<T> serviceType) {
+ return getService(serviceType, LoaderUtil.getClassLoaders());
+ }
+
+ public static <T> Optional<T> getService(final Class<T> serviceType,
ClassLoader classLoader) {
+ return getService(serviceType,
LoaderUtil.getClassLoaders(classLoader));
+ }
+
+ private static <T> Optional<T> getService(final Class<T> serviceType,
final ClassLoader[] classLoaders) {
+ final Logger logger = StatusLogger.getLogger();
// 1. Check for a system property with the FQCN of serviceType
- String serviceClassName =
PropertiesUtil.getProperties().getStringProperty(serviceType.getName());
- if (Strings.isNotEmpty(serviceClassName)) {
- try {
- @SuppressWarnings("unchecked")
- final Class<T> serviceClass = (Class<T>)
Class.forName(serviceClassName);
- if (serviceType.isAssignableFrom(serviceClass)) {
- return LoaderUtil.newInstanceOf(serviceClass);
- }
- getLogger().error("Unable to load service {}: it is not of the
required type {}", serviceClass,
- serviceType);
- } catch (ClassNotFoundException | InstantiationException |
IllegalAccessException
- | InvocationTargetException e) {
- getLogger().error("Unable to load service class {}",
serviceClassName, e);
+ try {
+ final T service =
LoaderUtil.newCheckedInstanceOfProperty(serviceType.getName(), serviceType);
+ if (service != null) {
+ return Optional.of(service);
}
+ } catch (ReflectiveOperationException | ClassCastException e) {
+ logger.error("Unable to load service class {}",
serviceType.getName(), e);
}
// 2. Use the ServiceLoader:
- final List<T> services = loadServices(serviceType,
- t -> getLogger().info("Unable to load service class for
service {}", serviceType.getName(), t));
+ final List<T> services = loadServices(serviceType, classLoaders,
true).collect(Collectors.toList());
if (services.size() > 0) {
if (services.size() > 1) {
- getLogger().warn("Multiple versions of service {} are
available on the classpath: {}", serviceType,
+ logger.warn("Multiple versions of service {} are available on
the classpath: {}", serviceType,
services);
}
- return services.get(0);
+ return Optional.of(services.get(0));
}
- return null;
+ return Optional.empty();
}
- static <T> List<T> loadServices(final Class<T> serviceType, final
Consumer<Throwable> logger) {
- final List<T> services = new ArrayList<T>();
- for (final ClassLoader loader : LoaderUtil.getClassLoaders()) {
- addServices(serviceType, loader, logger, services);
- }
+ static <T> Stream<T> loadServices(final Class<T> serviceType,
ClassLoader[] classLoaders, final boolean verbose) {
+ final Stream<T> services = Arrays.stream(classLoaders)
+ .flatMap(classLoader -> loadClassloaderServices(serviceType,
classLoader, verbose));
if (USE_HK2_SERVICE_LOCATOR) {
- addOsgiServices(serviceType, services);
+ try {
+ return Stream.concat(services, loadOsgiServices(serviceType));
+ } catch (Throwable e) {
+ if (verbose) {
+ StatusLogger.getLogger().error("Unable to load OSGI
services for service {}", serviceType, e);
+ }
+ }
}
return services;
Review comment:
I'll go for a single instance per class for now. The `Provider` service
overrides `equals/hashCode`, but the other service does not.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]