diff --git a/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnectionFactory.java b/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnectionFactory.java index 132814c1b97..7cbfd289093 100644 --- a/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnectionFactory.java +++ b/jetty-alpn/jetty-alpn-client/src/main/java/org/eclipse/jetty/alpn/client/ALPNClientConnectionFactory.java @@ -31,7 +31,7 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.NegotiatingClientConnectionFactory; import org.eclipse.jetty.io.ssl.ALPNProcessor.Client; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; -import org.eclipse.jetty.util.ServiceLoaderUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -54,7 +54,7 @@ public class ALPNClientConnectionFactory extends NegotiatingClientConnectionFact IllegalStateException failure = new IllegalStateException("No Client ALPNProcessors!"); // Use a for loop on iterator so load exceptions can be caught and ignored - for (Client processor : ServiceLoaderUtil.load(ServiceLoader.load(Client.class))) + for (Client processor : TypeUtil.loadAll(ServiceLoader.load(Client.class))) { try { diff --git a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java index 63d49d2caeb..50da92aab50 100644 --- a/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java +++ b/jetty-alpn/jetty-alpn-server/src/main/java/org/eclipse/jetty/alpn/server/ALPNServerConnectionFactory.java @@ -29,7 +29,7 @@ import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.ssl.ALPNProcessor.Server; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NegotiatingServerConnectionFactory; -import org.eclipse.jetty.util.ServiceLoaderUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -51,7 +51,7 @@ public class ALPNServerConnectionFactory extends NegotiatingServerConnectionFact IllegalStateException failure = new IllegalStateException("No Server ALPNProcessors!"); // Use a for loop on iterator so load exceptions can be caught and ignored - for (Server processor : ServiceLoaderUtil.load(ServiceLoader.load(Server.class))) + for (Server processor : TypeUtil.loadAll(ServiceLoader.load(Server.class))) { try { diff --git a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java index 407ac690db1..be37715de76 100644 --- a/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java +++ b/jetty-annotations/src/main/java/org/eclipse/jetty/annotations/AnnotationConfiguration.java @@ -48,7 +48,6 @@ import org.eclipse.jetty.plus.webapp.PlusConfiguration; import org.eclipse.jetty.util.JavaVersion; import org.eclipse.jetty.util.MultiException; import org.eclipse.jetty.util.ProcessorUtils; -import org.eclipse.jetty.util.ServiceLoaderUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; @@ -812,7 +811,7 @@ public class AnnotationConfiguration extends AbstractConfiguration long start = 0; if (LOG.isDebugEnabled()) start = System.nanoTime(); - List scis = ServiceLoaderUtil.load(ServiceLoader.load(ServletContainerInitializer.class)); + List scis = TypeUtil.loadAll(ServiceLoader.load(ServletContainerInitializer.class)); if (LOG.isDebugEnabled()) LOG.debug("Service loaders found in {}ms", (TimeUnit.MILLISECONDS.convert((System.nanoTime() - start), TimeUnit.NANOSECONDS))); diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java b/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java index 9236d3468dd..a25eb674f79 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/PreEncodedHttpField.java @@ -23,7 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.ServiceLoader; -import org.eclipse.jetty.util.ServiceLoaderUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -44,7 +44,7 @@ public class PreEncodedHttpField extends HttpField static { List encoders = new ArrayList<>(); - List discoveredEncoders = ServiceLoaderUtil.load(ServiceLoader.load(HttpFieldPreEncoder.class)); + List discoveredEncoders = TypeUtil.loadAll(ServiceLoader.load(HttpFieldPreEncoder.class)); for (HttpFieldPreEncoder encoder : discoveredEncoders) { if (index(encoder.getHttpVersion()) >= 0) diff --git a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java index dd1992868e8..702ae28b9fa 100644 --- a/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java +++ b/jetty-security/src/main/java/org/eclipse/jetty/security/SecurityHandler.java @@ -41,7 +41,7 @@ import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler.Context; import org.eclipse.jetty.server.handler.HandlerWrapper; -import org.eclipse.jetty.util.ServiceLoaderUtil; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.component.DumpableCollection; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -77,7 +77,7 @@ public abstract class SecurityHandler extends HandlerWrapper implements Authenti static { - __knownAuthenticatorFactories.addAll(ServiceLoaderUtil.load(ServiceLoader.load(Authenticator.Factory.class))); + __knownAuthenticatorFactories.addAll(TypeUtil.loadAll(ServiceLoader.load(Authenticator.Factory.class))); __knownAuthenticatorFactories.add(new DefaultAuthenticatorFactory()); } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ServiceLoaderUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ServiceLoaderUtil.java deleted file mode 100644 index 8edca00b74b..00000000000 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ServiceLoaderUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under -// the terms of the Eclipse Public License 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0 -// -// This Source Code may also be made available under the following -// Secondary Licenses when the conditions for such availability set -// forth in the Eclipse Public License, v. 2.0 are satisfied: -// the Apache License v2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.util; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ServiceConfigurationError; -import java.util.ServiceLoader; - -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class ServiceLoaderUtil -{ - private static final Logger LOG = Log.getLogger(ServiceLoaderUtil.class); - private static final int MAX_ERRORS = 100; - - /** - * Uses the {@link ServiceLoader} to assemble the service providers into a list. - * If loading a service type throws {@link ServiceConfigurationError}, - * it warns and continues iterating through the service loader. - * @param The class of the service type. - * @param serviceLoader The service loader to use. - * @return a list of the loaded service providers. - * @throws ServiceConfigurationError If the number of errors exceeds {@link #MAX_ERRORS} - */ - public static List load(ServiceLoader serviceLoader) - { - List list = new ArrayList<>(); - Iterator iterator = serviceLoader.iterator(); - - int errors = 0; - while (true) - { - try - { - if (!iterator.hasNext()) - break; - list.add(iterator.next()); - } - catch (ServiceConfigurationError e) - { - LOG.warn(e); - if (++errors >= MAX_ERRORS) - throw e; - } - } - - return list; - } -} diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java index bb3b80ca2ce..0b905643bd0 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/TypeUtil.java @@ -42,6 +42,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Optional; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -63,6 +65,7 @@ public class TypeUtil public static final int LF = '\n'; private static final HashMap> name2Class = new HashMap<>(); + private static final int MAX_ERRORS = 1000; static { @@ -751,4 +754,71 @@ public class TypeUtil } }; } + + /** + * Uses the {@link ServiceLoader} to assemble the service providers into a list. + * If loading a service type throws {@link ServiceConfigurationError}, + * it warns and continues iterating through the service loader. + * @param The class of the service type. + * @param serviceLoader The service loader to use. + * @return a list of the loaded service providers. + * @throws ServiceConfigurationError If the number of errors exceeds {@link #MAX_ERRORS} + */ + public static List loadAll(ServiceLoader serviceLoader) + { + List list = new ArrayList<>(); + Iterator iterator = serviceLoader.iterator(); + + int errors = 0; + while (true) + { + try + { + if (!iterator.hasNext()) + break; + list.add(iterator.next()); + } + catch (ServiceConfigurationError e) + { + LOG.warn(e); + if (++errors >= MAX_ERRORS) + throw e; + } + } + + return list; + } + + /** + * Uses the {@link ServiceLoader} to get the first availible service provider. + * If loading a service type throws {@link ServiceConfigurationError}, + * it warns and continues iterating through the service loader until one is found. + * @param The class of the service type. + * @param serviceLoader The service loader to use. + * @return an instance of a service provider, or null if none could be found. + * @throws ServiceConfigurationError If the number of errors exceeds {@link #MAX_ERRORS} + */ + public static T loadFirst(ServiceLoader serviceLoader) + { + Iterator iterator = serviceLoader.iterator(); + + int errors = 0; + while (true) + { + try + { + if (!iterator.hasNext()) + break; + return iterator.next(); + } + catch (ServiceConfigurationError e) + { + LOG.warn(e); + if (++errors >= MAX_ERRORS) + throw e; + } + } + + return null; + } } diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java index bcf4d202434..de689e50fad 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/security/Credential.java @@ -24,7 +24,6 @@ import java.security.MessageDigest; import java.util.List; import java.util.ServiceLoader; -import org.eclipse.jetty.util.ServiceLoaderUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; @@ -44,7 +43,7 @@ public abstract class Credential implements Serializable { private static final long serialVersionUID = -7760551052768181572L; private static final Logger LOG = Log.getLogger(Credential.class); - private static final List CREDENTIAL_PROVIDERS = ServiceLoaderUtil.load(ServiceLoader.load(CredentialProvider.class)); + private static final List CREDENTIAL_PROVIDERS = TypeUtil.loadAll(ServiceLoader.load(CredentialProvider.class)); /** * Check a credential diff --git a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java index 51c36b8de18..01d08f3be4f 100644 --- a/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java +++ b/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/Configurations.java @@ -36,8 +36,8 @@ import java.util.stream.Collectors; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.Loader; -import org.eclipse.jetty.util.ServiceLoaderUtil; import org.eclipse.jetty.util.TopologicalSort; +import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.DumpableCollection; @@ -75,7 +75,7 @@ public class Configurations extends AbstractList implements Dumpa { if (__known.isEmpty()) { - List configs = ServiceLoaderUtil.load(ServiceLoader.load(Configuration.class)); + List configs = TypeUtil.loadAll(ServiceLoader.load(Configuration.class)); for (Configuration configuration : configs) { if (!configuration.isAvailable()) diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index 80947c0ec69..b44cea00d74 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -55,7 +55,6 @@ import java.util.Set; import org.eclipse.jetty.util.LazyList; import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.MultiException; -import org.eclipse.jetty.util.ServiceLoaderUtil; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.annotation.Name; @@ -96,7 +95,7 @@ public class XmlConfiguration { ArrayList.class, HashSet.class, Queue.class, List.class, Set.class, Collection.class }; - private static final List PROCESSOR_FACTORIES = ServiceLoaderUtil.load(ServiceLoader.load(ConfigurationProcessorFactory.class)); + private static final List PROCESSOR_FACTORIES = TypeUtil.loadAll(ServiceLoader.load(ConfigurationProcessorFactory.class)); private static final XmlParser PARSER = initParser(); private static final Comparator EXECUTABLE_COMPARATOR = (o1, o2) -> {