260 } else { |
260 } else { |
261 systemProp = System.getProperty(factoryId); |
261 systemProp = System.getProperty(factoryId); |
262 } |
262 } |
263 if (systemProp != null) { |
263 if (systemProp != null) { |
264 dPrint("found system property, value=" + systemProp); |
264 dPrint("found system property, value=" + systemProp); |
265 // There's a bug here - because 'cl' is ignored. |
265 return newInstance(type, systemProp, cl, true); |
266 // This will be handled separately. |
|
267 return newInstance(type, systemProp, null, true); |
|
268 } |
266 } |
269 } |
267 } |
270 catch (SecurityException se) { |
268 catch (SecurityException se) { |
271 throw new FactoryConfigurationError( |
269 throw new FactoryConfigurationError( |
272 "Failed to read factoryId '" + factoryId + "'", se); |
270 "Failed to read factoryId '" + factoryId + "'", se); |
301 } |
299 } |
302 final String factoryClassName = cacheProps.getProperty(factoryId); |
300 final String factoryClassName = cacheProps.getProperty(factoryId); |
303 |
301 |
304 if (factoryClassName != null) { |
302 if (factoryClassName != null) { |
305 dPrint("found in " + configFile + " value=" + factoryClassName); |
303 dPrint("found in " + configFile + " value=" + factoryClassName); |
306 // There's a bug here - because 'cl' is ignored. |
304 return newInstance(type, factoryClassName, cl, true); |
307 // This will be handled separately. |
|
308 return newInstance(type, factoryClassName, null, true); |
|
309 } |
305 } |
310 } |
306 } |
311 catch (Exception ex) { |
307 catch (Exception ex) { |
312 if (debug) ex.printStackTrace(); |
308 if (debug) ex.printStackTrace(); |
313 } |
309 } |
314 |
310 |
315 if (type.getName().equals(factoryId)) { |
311 if (type.getName().equals(factoryId)) { |
316 // Try Jar Service Provider Mechanism |
312 // Try Jar Service Provider Mechanism |
317 final T provider = findServiceProvider(type); |
313 final T provider = findServiceProvider(type, cl); |
318 if (provider != null) { |
314 if (provider != null) { |
319 return provider; |
315 return provider; |
320 } |
316 } |
321 } else { |
317 } else { |
322 // We're in the case where a 'custom' factoryId was provided, |
318 // We're in the case where a 'custom' factoryId was provided, |
338 * |
334 * |
339 * @param type Base class / Service interface of the factory to find. |
335 * @param type Base class / Service interface of the factory to find. |
340 * |
336 * |
341 * @return instance of provider class if found or null |
337 * @return instance of provider class if found or null |
342 */ |
338 */ |
343 private static <T> T findServiceProvider(final Class<T> type) { |
339 private static <T> T findServiceProvider(final Class<T> type, final ClassLoader cl) { |
344 try { |
340 try { |
345 return AccessController.doPrivileged(new PrivilegedAction<T>() { |
341 return AccessController.doPrivileged(new PrivilegedAction<T>() { |
346 @Override |
342 @Override |
347 public T run() { |
343 public T run() { |
348 final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); |
344 final ServiceLoader<T> serviceLoader; |
|
345 if (cl == null) { |
|
346 //the current thread's context class loader |
|
347 serviceLoader = ServiceLoader.load(type); |
|
348 } else { |
|
349 serviceLoader = ServiceLoader.load(type, cl); |
|
350 } |
349 final Iterator<T> iterator = serviceLoader.iterator(); |
351 final Iterator<T> iterator = serviceLoader.iterator(); |
350 if (iterator.hasNext()) { |
352 if (iterator.hasNext()) { |
351 return iterator.next(); |
353 return iterator.next(); |
352 } else { |
354 } else { |
353 return null; |
355 return null; |