93 * tried. |
94 * tried. |
94 * |
95 * |
95 * If the class loader supplied is <code>null</code>, first try using the |
96 * If the class loader supplied is <code>null</code>, first try using the |
96 * context class loader followed by the current (i.e. bootstrap) class |
97 * context class loader followed by the current (i.e. bootstrap) class |
97 * loader. |
98 * loader. |
|
99 * |
|
100 * Use bootstrap classLoader if cl = null and useBSClsLoader is true |
98 */ |
101 */ |
99 static private Class getProviderClass(String className, ClassLoader cl, |
102 static private Class getProviderClass(String className, ClassLoader cl, |
100 boolean doFallback) throws ClassNotFoundException |
103 boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException |
101 { |
104 { |
102 try { |
105 try { |
103 if (cl == null) { |
106 if (cl == null) { |
104 cl = ss.getContextClassLoader(); |
107 if (useBSClsLoader) { |
105 if (cl == null) { |
108 return Class.forName(className, true, FactoryFinder.class.getClassLoader()); |
106 throw new ClassNotFoundException(); |
109 } else { |
107 } |
110 cl = ss.getContextClassLoader(); |
108 else { |
111 if (cl == null) { |
109 return cl.loadClass(className); |
112 throw new ClassNotFoundException(); |
|
113 } |
|
114 else { |
|
115 return cl.loadClass(className); |
|
116 } |
110 } |
117 } |
111 } |
118 } |
112 else { |
119 else { |
113 return cl.loadClass(className); |
120 return cl.loadClass(className); |
114 } |
121 } |
129 * <code>getProviderClass()</code> in order to load the class. |
136 * <code>getProviderClass()</code> in order to load the class. |
130 * |
137 * |
131 * @param className Name of the concrete class corresponding to the |
138 * @param className Name of the concrete class corresponding to the |
132 * service provider |
139 * service provider |
133 * |
140 * |
|
141 * @param cl <code>ClassLoader</code> used to load the factory class. If <code>null</code> |
|
142 * current <code>Thread</code>'s context classLoader is used to load the factory class. |
|
143 * |
|
144 * @param doFallback True if the current ClassLoader should be tried as |
|
145 * a fallback if the class is not found using cl |
|
146 */ |
|
147 static Object newInstance(String className, ClassLoader cl, boolean doFallback) |
|
148 throws ConfigurationError |
|
149 { |
|
150 return newInstance(className, cl, doFallback, false); |
|
151 } |
|
152 |
|
153 /** |
|
154 * Create an instance of a class. Delegates to method |
|
155 * <code>getProviderClass()</code> in order to load the class. |
|
156 * |
|
157 * @param className Name of the concrete class corresponding to the |
|
158 * service provider |
|
159 * |
134 * @param cl ClassLoader to use to load the class, null means to use |
160 * @param cl ClassLoader to use to load the class, null means to use |
135 * the bootstrap ClassLoader |
161 * the bootstrap ClassLoader |
136 * |
162 * |
137 * @param doFallback True if the current ClassLoader should be tried as |
163 * @param doFallback True if the current ClassLoader should be tried as |
138 * a fallback if the class is not found using cl |
164 * a fallback if the class is not found using cl |
139 */ |
165 * |
140 static Object newInstance(String className, ClassLoader cl, boolean doFallback) |
166 * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter |
|
167 * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. |
|
168 */ |
|
169 static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) |
141 throws ConfigurationError |
170 throws ConfigurationError |
142 { |
171 { |
143 try { |
172 // make sure we have access to restricted packages |
144 Class providerClass = getProviderClass(className, cl, doFallback); |
173 if (System.getSecurityManager() != null) { |
|
174 if (className != null && className.startsWith(DEFAULT_PACKAGE)) { |
|
175 cl = null; |
|
176 useBSClsLoader = true; |
|
177 } |
|
178 } |
|
179 |
|
180 try { |
|
181 Class providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); |
145 Object instance = providerClass.newInstance(); |
182 Object instance = providerClass.newInstance(); |
146 if (debug) { // Extra check to avoid computing cl strings |
183 if (debug) { // Extra check to avoid computing cl strings |
147 dPrint("created new instance of " + providerClass + |
184 dPrint("created new instance of " + providerClass + |
148 " using ClassLoader: " + cl); |
185 " using ClassLoader: " + cl); |
149 } |
186 } |
242 String serviceId = "META-INF/services/" + factoryId; |
279 String serviceId = "META-INF/services/" + factoryId; |
243 InputStream is = null; |
280 InputStream is = null; |
244 |
281 |
245 // First try the Context ClassLoader |
282 // First try the Context ClassLoader |
246 ClassLoader cl = ss.getContextClassLoader(); |
283 ClassLoader cl = ss.getContextClassLoader(); |
|
284 boolean useBSClsLoader = false; |
247 if (cl != null) { |
285 if (cl != null) { |
248 is = ss.getResourceAsStream(cl, serviceId); |
286 is = ss.getResourceAsStream(cl, serviceId); |
249 |
287 |
250 // If no provider found then try the current ClassLoader |
288 // If no provider found then try the current ClassLoader |
251 if (is == null) { |
289 if (is == null) { |
252 cl = FactoryFinder.class.getClassLoader(); |
290 cl = FactoryFinder.class.getClassLoader(); |
253 is = ss.getResourceAsStream(cl, serviceId); |
291 is = ss.getResourceAsStream(cl, serviceId); |
|
292 useBSClsLoader = true; |
254 } |
293 } |
255 } else { |
294 } else { |
256 // No Context ClassLoader, try the current ClassLoader |
295 // No Context ClassLoader, try the current ClassLoader |
257 cl = FactoryFinder.class.getClassLoader(); |
296 cl = FactoryFinder.class.getClassLoader(); |
258 is = ss.getResourceAsStream(cl, serviceId); |
297 is = ss.getResourceAsStream(cl, serviceId); |
|
298 useBSClsLoader = true; |
259 } |
299 } |
260 |
300 |
261 if (is == null) { |
301 if (is == null) { |
262 // No provider found |
302 // No provider found |
263 return null; |
303 return null; |
291 |
331 |
292 // Note: here we do not want to fall back to the current |
332 // Note: here we do not want to fall back to the current |
293 // ClassLoader because we want to avoid the case where the |
333 // ClassLoader because we want to avoid the case where the |
294 // resource file was found using one ClassLoader and the |
334 // resource file was found using one ClassLoader and the |
295 // provider class was instantiated using a different one. |
335 // provider class was instantiated using a different one. |
296 return newInstance(factoryClassName, cl, false); |
336 return newInstance(factoryClassName, cl, false, useBSClsLoader); |
297 } |
337 } |
298 |
338 |
299 // No provider found |
339 // No provider found |
300 return null; |
340 return null; |
301 } |
341 } |