3333import java .util .ArrayList ;
3434import java .util .Arrays ;
3535import java .util .Enumeration ;
36- import java .util .Iterator ;
3736import java .util .LinkedHashSet ;
3837import java .util .List ;
38+ import java .util .Objects ;
3939import java .util .ServiceConfigurationError ;
4040import java .util .ServiceLoader ;
41+ import java .util .ServiceLoader .Provider ;
4142import java .util .Set ;
4243import java .util .concurrent .LinkedBlockingQueue ;
44+ import java .util .stream .Collectors ;
45+ import java .util .stream .Stream ;
4346
4447import org .slf4j .event .SubstituteLoggingEvent ;
4548import org .slf4j .helpers .NOP_FallbackServiceProvider ;
@@ -110,24 +113,32 @@ public final class LoggerFactory {
110113
111114 // Package access for tests
112115 static List <SLF4JServiceProvider > findServiceProviders () {
113- List <SLF4JServiceProvider > providerList = new ArrayList <>();
114116
115117 // retain behaviour similar to that of 1.7 series and earlier. More specifically, use the class loader that
116118 // loaded the present class to search for services
117119 final ClassLoader classLoaderOfLoggerFactory = LoggerFactory .class .getClassLoader ();
118120
119- SLF4JServiceProvider explicitProvider = loadExplicitlySpecified (classLoaderOfLoggerFactory );
120- if (explicitProvider != null ) {
121- providerList .add (explicitProvider );
122- return providerList ;
123- }
124-
121+
122+ ServiceLoader <SLF4JServiceProvider > serviceLoader = getServiceLoader (classLoaderOfLoggerFactory );
125123
126- ServiceLoader < SLF4JServiceProvider > serviceLoader = getServiceLoader ( classLoaderOfLoggerFactory );
124+ Stream < Provider < SLF4JServiceProvider >> stream = serviceLoader . stream ( );
127125
128- Iterator <SLF4JServiceProvider > iterator = serviceLoader .iterator ();
129- while (iterator .hasNext ()) {
130- safelyInstantiate (providerList , iterator );
126+ String explicitlySpecified = System .getProperty (PROVIDER_PROPERTY_KEY , "" );
127+
128+ if (!explicitlySpecified .isEmpty ()) {
129+ stream = stream .filter (s -> s .type ().getName ().equals (explicitlySpecified ));
130+ }
131+
132+ List <SLF4JServiceProvider > providerList = stream .map (LoggerFactory ::safelyInstantiate )
133+ .filter (Objects ::nonNull )
134+ .collect (Collectors .toList ());
135+
136+ if (providerList .isEmpty () && !explicitlySpecified .isEmpty ())
137+ {
138+ SLF4JServiceProvider explicitProvider = loadExplicitlySpecified (explicitlySpecified , classLoaderOfLoggerFactory );
139+ if (explicitProvider != null ) {
140+ return Arrays .asList (explicitProvider );
141+ }
131142 }
132143 return providerList ;
133144 }
@@ -144,13 +155,18 @@ private static ServiceLoader<SLF4JServiceProvider> getServiceLoader(final ClassL
144155 return serviceLoader ;
145156 }
146157
147- private static void safelyInstantiate (List <SLF4JServiceProvider > providerList , Iterator <SLF4JServiceProvider > iterator ) {
158+ /**
159+ *
160+ * @param provider
161+ * @return the initiated provider or {@code null} if it fails
162+ */
163+ private static SLF4JServiceProvider safelyInstantiate (Provider <SLF4JServiceProvider > provider ) {
148164 try {
149- SLF4JServiceProvider provider = iterator .next ();
150- providerList .add (provider );
165+ return provider .get ();
151166 } catch (ServiceConfigurationError e ) {
152167 Reporter .error ("A service provider failed to instantiate:\n " + e .getMessage ());
153168 }
169+ return null ;
154170 }
155171
156172 /**
@@ -212,11 +228,13 @@ private final static void bind() {
212228 }
213229 }
214230
215- static SLF4JServiceProvider loadExplicitlySpecified (ClassLoader classLoader ) {
216- String explicitlySpecified = System .getProperty (PROVIDER_PROPERTY_KEY );
217- if (null == explicitlySpecified || explicitlySpecified .isEmpty ()) {
218- return null ;
219- }
231+ /**
232+ *
233+ * @param explicitlySpecified the classname of the provider, never {@code null}
234+ * @param classLoader the classloader, never {@code null}
235+ * @return
236+ */
237+ static SLF4JServiceProvider loadExplicitlySpecified (String explicitlySpecified , ClassLoader classLoader ) {
220238 try {
221239 String message = String .format ("Attempting to load provider \" %s\" specified via \" %s\" system property" , explicitlySpecified , PROVIDER_PROPERTY_KEY );
222240 Reporter .info (message );
0 commit comments