1010import java .util .Arrays ;
1111import java .util .Comparator ;
1212import java .util .Optional ;
13+ import java .util .ServiceConfigurationError ;
1314import java .util .ServiceLoader ;
1415import java .util .stream .Stream ;
1516
@@ -47,7 +48,7 @@ public static <T> Stream<T> loadAll(Class<T> clazz) {
4748 .filter (IntegrationsLoader ::isSupportedOperatingSystem )
4849 .filter (IntegrationsLoader ::passesStaticAvailabilityCheck )
4950 .sorted (Comparator .comparingInt (IntegrationsLoader ::getPriority ).reversed ())
50- .map ( ServiceLoader . Provider :: get )
51+ .flatMap ( IntegrationsLoader :: instantiateServiceProvider )
5152 .filter (IntegrationsLoader ::passesInstanceAvailabilityCheck )
5253 .peek (impl -> logServiceIsAvailable (clazz , impl .getClass ()));
5354 }
@@ -68,18 +69,30 @@ private static boolean isSupportedOperatingSystem(ServiceLoader.Provider<?> prov
6869 return annotations .length == 0 || Arrays .stream (annotations ).anyMatch (OperatingSystem .Value ::isCurrent );
6970 }
7071
72+ private static <T > Stream <T > instantiateServiceProvider (ServiceLoader .Provider <T > provider ) {
73+ try {
74+ return Stream .of (provider .get ());
75+ } catch (ServiceConfigurationError err ) {
76+ //ServiceLoader.Provider::get throws this error if (from javadoc)
77+ // * the public static "provider()" method of a provider factory returns null
78+ // * the service provider cannot be instantiated due to an error/throw
79+ LOG .warn ("Unable to load service provider {}." , provider .type ().getName (), err );
80+ return Stream .empty ();
81+ }
82+ }
83+
7184 private static boolean passesStaticAvailabilityCheck (ServiceLoader .Provider <?> provider ) {
7285 return passesStaticAvailabilityCheck (provider .type ());
7386 }
7487
7588 @ VisibleForTesting
7689 static boolean passesStaticAvailabilityCheck (Class <?> type ) {
77- return passesAvailabilityCheck (type , null );
90+ return silentlyPassesAvailabilityCheck (type , null );
7891 }
7992
8093 @ VisibleForTesting
8194 static boolean passesInstanceAvailabilityCheck (Object instance ) {
82- return passesAvailabilityCheck (instance .getClass (), instance );
95+ return silentlyPassesAvailabilityCheck (instance .getClass (), instance );
8396 }
8497
8598 private static void logServiceIsAvailable (Class <?> apiType , Class <?> implType ) {
@@ -88,6 +101,15 @@ private static void logServiceIsAvailable(Class<?> apiType, Class<?> implType) {
88101 }
89102 }
90103
104+ private static <T > boolean silentlyPassesAvailabilityCheck (Class <? extends T > type , @ Nullable T instance ) {
105+ try {
106+ return passesAvailabilityCheck (type , instance );
107+ } catch (ExceptionInInitializerError | NoClassDefFoundError | RuntimeException e ) {
108+ LOG .warn ("Unable to load service provider {}." , type .getName (), e );
109+ return false ;
110+ }
111+ }
112+
91113 private static <T > boolean passesAvailabilityCheck (Class <? extends T > type , @ Nullable T instance ) {
92114 if (!type .isAnnotationPresent (CheckAvailability .class )) {
93115 return true ; // if type is not annotated, skip tests
0 commit comments