1
1
/*
2
- * Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2010, 2022 Oracle and/or its affiliates. All rights reserved.
3
3
*
4
4
* This program and the accompanying materials are made available under the
5
5
* terms of the Eclipse Public License v. 2.0, which is available at
31
31
import java .util .Iterator ;
32
32
import java .util .List ;
33
33
import java .util .NoSuchElementException ;
34
+ import java .util .ServiceLoader ;
34
35
import java .util .Set ;
35
36
import java .util .TreeSet ;
36
37
import java .util .logging .Level ;
37
38
import java .util .logging .Logger ;
39
+ import java .util .stream .Collectors ;
38
40
39
41
import org .glassfish .jersey .internal .util .ReflectionHelper ;
40
42
@@ -229,7 +231,9 @@ public static <T> ServiceFinder<T> find(final Class<T> service, final ClassLoade
229
231
* class loader (or, failing that the bootstrap class loader) is to
230
232
* be used
231
233
* @param ignoreOnClassNotFound If a provider cannot be loaded by the class loader
232
- * then move on to the next available provider.
234
+ * then move on to the next available provider. This value does
235
+ * not apply when the {@link ServiceIteratorProvider} is set to
236
+ * {@link ServiceLookupIteratorProvider}.
233
237
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
234
238
* or names a provider class that cannot be found and instantiated
235
239
* @see #find(Class)
@@ -279,7 +283,10 @@ public static <T> ServiceFinder<T> find(final Class<T> service)
279
283
* </pre>
280
284
* @param service The service's abstract service class
281
285
* @param ignoreOnClassNotFound If a provider cannot be loaded by the class loader
282
- * then move on to the next available provider.
286
+ * then move on to the next available provider. This value does
287
+ * not apply when the {@link ServiceIteratorProvider} is set to
288
+ * {@link ServiceLookupIteratorProvider}.
289
+ *
283
290
* @throws ServiceConfigurationError If a provider-configuration file violates the specified format
284
291
* or names a provider class that cannot be found and instantiated
285
292
* @see #find(Class, ClassLoader)
@@ -312,7 +319,7 @@ public static ServiceFinder<?> find(final String serviceName) throws ServiceConf
312
319
* Register the service iterator provider to iterate on provider instances
313
320
* or classes.
314
321
* <p>
315
- * The default implementation registered, {@link DefaultServiceIteratorProvider },
322
+ * The default implementation registered, {@link ServiceLookupIteratorProvider },
316
323
* looks up provider classes in META-INF/service files.
317
324
* <p>
318
325
* This method must be called prior to any attempts to obtain provider
@@ -790,7 +797,7 @@ private void handleClassNotFoundException() throws ServiceConfigurationError {
790
797
* Supports iteration of provider instances or classes.
791
798
* <p>
792
799
* The default implementation looks up provider classes from META-INF/services
793
- * files, see {@link DefaultServiceIteratorProvider }.
800
+ * files, see {@link ServiceLookupIteratorProvider }.
794
801
* This implementation may be overridden by invoking
795
802
* {@link ServiceFinder#setIteratorProvider(org.glassfish.jersey.internal.ServiceFinder.ServiceIteratorProvider)}.
796
803
*/
@@ -806,7 +813,7 @@ private static ServiceIteratorProvider getInstance() {
806
813
synchronized (sipLock ) {
807
814
result = sip ;
808
815
if (result == null ) { // Second check (with locking)
809
- sip = result = new DefaultServiceIteratorProvider ();
816
+ sip = result = new ServiceLookupIteratorProvider ();
810
817
}
811
818
}
812
819
}
@@ -834,7 +841,9 @@ private static void setInstance(final ServiceIteratorProvider sip) throws Securi
834
841
* classes.
835
842
* @param ignoreOnClassNotFound if true ignore an instance if the
836
843
* corresponding provider class if cannot be found,
837
- * otherwise throw a {@link ClassNotFoundException}.
844
+ * otherwise throw a {@link ClassNotFoundException}. This value does
845
+ * not apply when the {@link ServiceIteratorProvider} is set to
846
+ * {@link ServiceLookupIteratorProvider}.
838
847
* @return the provider instance iterator.
839
848
*/
840
849
public abstract <T > Iterator <T > createIterator (Class <T > service ,
@@ -851,6 +860,8 @@ public abstract <T> Iterator<T> createIterator(Class<T> service,
851
860
* @param ignoreOnClassNotFound if true ignore the provider class if
852
861
* cannot be found,
853
862
* otherwise throw a {@link ClassNotFoundException}.
863
+ * This value does not apply when the {@link ServiceIteratorProvider}
864
+ * is set to {@link ServiceLookupIteratorProvider}.
854
865
* @return the provider class iterator.
855
866
*/
856
867
public abstract <T > Iterator <Class <T >> createClassIterator (Class <T > service ,
@@ -860,13 +871,10 @@ public abstract <T> Iterator<Class<T>> createClassIterator(Class<T> service,
860
871
}
861
872
862
873
/**
863
- * The default service iterator provider that looks up provider classes in
874
+ * The service iterator provider that looks up provider classes in
864
875
* META-INF/services files.
865
- * <p>
866
- * This class may utilized if a {@link ServiceIteratorProvider} needs to
867
- * reuse the default implementation.
868
876
*/
869
- public static final class DefaultServiceIteratorProvider extends ServiceIteratorProvider {
877
+ public static final class ServiceReflectionIteratorProvider extends ServiceIteratorProvider {
870
878
871
879
@ Override
872
880
public <T > Iterator <T > createIterator (final Class <T > service , final String serviceName ,
@@ -880,4 +888,41 @@ public <T> Iterator<Class<T>> createClassIterator(final Class<T> service, final
880
888
return new LazyClassIterator <T >(service , serviceName , loader , ignoreOnClassNotFound );
881
889
}
882
890
}
891
+
892
+ /**
893
+ * The service iterator provider that looks up provider classes in
894
+ * META-INF/services files using {@link ServiceLoader}.
895
+ */
896
+ public static final class ServiceLookupIteratorProvider extends ServiceIteratorProvider {
897
+
898
+ @ Override
899
+ public <T > Iterator <T > createIterator (final Class <T > service , final String serviceName ,
900
+ final ClassLoader loader , final boolean ignoreOnClassNotFound ) {
901
+ Class <T > clazz = fixGenericService (service , serviceName , loader , ignoreOnClassNotFound );
902
+ return ServiceLoader .load (clazz , loader ).iterator ();
903
+ }
904
+
905
+ @ Override
906
+ public <T > Iterator <Class <T >> createClassIterator (final Class <T > service , final String serviceName ,
907
+ final ClassLoader loader , final boolean ignoreOnClassNotFound ) {
908
+ Class <T > clazz = fixGenericService (service , serviceName , loader , ignoreOnClassNotFound );
909
+ List <Class <T >> classes = ServiceLoader .load (clazz , loader ).stream ()
910
+ .map (provider -> (Class <T >) provider .type ())
911
+ .collect (Collectors .toList ());
912
+ return classes .iterator ();
913
+ }
914
+
915
+ private <T > Class <T > fixGenericService (final Class <T > service , final String serviceName ,
916
+ final ClassLoader loader , final boolean ignoreOnClassNotFound ) {
917
+ Class <T > clazz = service ;
918
+ if (Object .class == service ) {
919
+ try {
920
+ clazz = (Class <T >) ReflectionHelper .classForNameWithExceptionPEA (serviceName , loader ).run ();
921
+ } catch (Exception e ) {
922
+ // Ignore it. Later, the service implementation will not be loaded.
923
+ }
924
+ }
925
+ return clazz ;
926
+ }
927
+ }
883
928
}
0 commit comments