comparison graal/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java @ 21760:55058b8000ea

updated javadoc to document that JVMCI services are disjoint from the standard service loading mechanism and tightened generic type constraint such that Services and @ServiceProcessor can only be used with classes implementing Service
author Doug Simon <doug.simon@oracle.com>
date Sat, 06 Jun 2015 09:23:37 +0200
parents 2e8c01def9a5
children
comparison
equal deleted inserted replaced
21759:75daca0c6a0f 21760:55058b8000ea
25 import java.util.*; 25 import java.util.*;
26 26
27 import sun.reflect.*; 27 import sun.reflect.*;
28 28
29 /** 29 /**
30 * A mechanism on top of the standard {@link ServiceLoader} that enables JVMCI enabled runtime to 30 * An mechanism for loading {@linkplain Service JVMCI services}.
31 * efficiently load services marked by {@link Service}. This is important to avoid the performance
32 * overhead of the standard service loader mechanism for services loaded in the runtime
33 * initialization process.
34 */ 31 */
35 public class Services { 32 public class Services {
36 33
37 /** 34 /**
38 * Determines whether to suppress the {@link NoClassDefFoundError} raised if a service 35 * Determines whether to suppress the {@link NoClassDefFoundError} raised if a service
53 } 50 }
54 } 51 }
55 }; 52 };
56 53
57 /** 54 /**
58 * Gets an {@link Iterable} of the implementations available for a given service. 55 * Gets an {@link Iterable} of the implementations available for a given JVMCI service.
59 * 56 *
60 * @throws SecurityException if a security manager is present and it denies 57 * @throws SecurityException if a security manager is present and it denies
61 * <tt>{@link RuntimePermission}("jvmciServices")</tt> 58 * <tt>{@link RuntimePermission}("jvmciServices")</tt>
62 */ 59 */
63 @SuppressWarnings("unchecked") 60 @SuppressWarnings("unchecked")
64 @CallerSensitive 61 @CallerSensitive
65 public static <S> Iterable<S> load(Class<S> service) { 62 public static <S extends Service> Iterable<S> load(Class<S> service) {
66 SecurityManager sm = System.getSecurityManager(); 63 SecurityManager sm = System.getSecurityManager();
67 if (sm != null) { 64 if (sm != null) {
68 sm.checkPermission(new RuntimePermission("jvmciServices")); 65 sm.checkPermission(new RuntimePermission("jvmciServices"));
69 } 66 }
70 if (Service.class.isAssignableFrom(service)) { 67 try {
71 try { 68 return (Iterable<S>) cache.get(service);
72 return (Iterable<S>) cache.get(service); 69 } catch (UnsatisfiedLinkError e) {
73 } catch (UnsatisfiedLinkError e) { 70 return Collections.emptyList();
74 // Fall back to standard ServiceLoader
75 }
76 } 71 }
77
78 // Need to use the ClassLoader of the caller
79 ClassLoader cl = Reflection.getCallerClass().getClassLoader();
80 return ServiceLoader.load(service, cl);
81 } 72 }
82 73
83 /** 74 /**
84 * Gets the implementation for a given service for which at most one implementation must be 75 * Gets the implementation for a given service for which at most one implementation must be
85 * available. 76 * available.
90 * @throws SecurityException if a security manager is present and it denies 81 * @throws SecurityException if a security manager is present and it denies
91 * <tt>{@link RuntimePermission}("jvmciServices")</tt> 82 * <tt>{@link RuntimePermission}("jvmciServices")</tt>
92 */ 83 */
93 @SuppressWarnings("unchecked") 84 @SuppressWarnings("unchecked")
94 @CallerSensitive 85 @CallerSensitive
95 public static <S> S loadSingle(Class<S> service, boolean required) { 86 public static <S extends Service> S loadSingle(Class<S> service, boolean required) {
96 SecurityManager sm = System.getSecurityManager(); 87 SecurityManager sm = System.getSecurityManager();
97 if (sm != null) { 88 if (sm != null) {
98 sm.checkPermission(new RuntimePermission("jvmciServices")); 89 sm.checkPermission(new RuntimePermission("jvmciServices"));
99 } 90 }
100 Iterable<S> impls; 91 Iterable<S> impls;
101 if (Service.class.isAssignableFrom(service)) { 92 try {
102 try { 93 impls = (Iterable<S>) cache.get(service);
103 impls = (Iterable<S>) cache.get(service); 94 } catch (UnsatisfiedLinkError e) {
104 } catch (UnsatisfiedLinkError e) { 95 impls = Collections.emptyList();
105 // Fall back to standard ServiceLoader
106 impls = null;
107 }
108 } else {
109 impls = null;
110 } 96 }
111 97
112 if (impls == null) {
113 // Need to use the ClassLoader of the caller
114 ClassLoader cl = Reflection.getCallerClass().getClassLoader();
115 impls = ServiceLoader.load(service, cl);
116 }
117 S singleImpl = null; 98 S singleImpl = null;
118 for (S impl : impls) { 99 for (S impl : impls) {
119 if (singleImpl != null) { 100 if (singleImpl != null) {
120 throw new InternalError(String.format("Multiple %s implementations found: %s, %s", service.getName(), singleImpl.getClass().getName(), impl.getClass().getName())); 101 throw new InternalError(String.format("Multiple %s implementations found: %s, %s", service.getName(), singleImpl.getClass().getName(), impl.getClass().getName()));
121 } 102 }