1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // © 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 2015, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 package android.icu.impl; 11 12 import java.security.AccessController; 13 import java.security.PrivilegedAction; 14 15 16 /** 17 * This utility class is used for resolving a right ClassLoader from 18 * a given class. getClassLoader always returns a non-null ClassLoader 19 * even a class is loaded through the bootstrap class loader of JRE. 20 * @hide Only a subset of ICU is exposed in Android 21 */ 22 public class ClassLoaderUtil { 23 24 private static class BootstrapClassLoader extends ClassLoader { BootstrapClassLoader()25 BootstrapClassLoader() { 26 // Object.class.getClassLoader() may return null. 27 // 28 // On Android, the behavior of super(null) is not guaranteed, 29 // but Object.class.getClassLoader() actually returns the 30 // bootstrap class loader. Note that we probably do not reach 31 // this constructor on Android, because ClassLoaderUtil.getClassLoader() 32 // should get non-null ClassLoader before calling 33 // ClassLoaderUtil.getBootstrapClassLoader(). 34 // 35 // On other common JREs (such as Oracle, OpenJDK), 36 // Object.class.getClassLoader() returns null, but 37 // super(null) is commonly used for accessing the bootstrap 38 // class loader. 39 super(Object.class.getClassLoader()); 40 } 41 } 42 43 private static volatile ClassLoader BOOTSTRAP_CLASSLOADER; 44 45 /** 46 * Lazily create a singleton BootstrapClassLoader. 47 * This class loader might be necessary when ICU4J classes are 48 * initialized by bootstrap class loader. 49 * 50 * @return The BootStrapClassLoader singleton instance 51 */ getBootstrapClassLoader()52 private static ClassLoader getBootstrapClassLoader() { 53 if (BOOTSTRAP_CLASSLOADER == null) { 54 synchronized(ClassLoaderUtil.class) { 55 if (BOOTSTRAP_CLASSLOADER == null) { 56 ClassLoader cl = null; 57 if (System.getSecurityManager() != null) { 58 cl = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { 59 @Override 60 public BootstrapClassLoader run() { 61 return new BootstrapClassLoader(); 62 } 63 }); 64 } else { 65 cl = new BootstrapClassLoader(); 66 } 67 BOOTSTRAP_CLASSLOADER = cl; 68 } 69 } 70 } 71 return BOOTSTRAP_CLASSLOADER; 72 } 73 74 75 /** 76 * Returns the class loader used for loading the specified class. 77 * @param cls The class 78 * @return the class loader 79 */ getClassLoader(Class<?> cls)80 public static ClassLoader getClassLoader(Class<?> cls) { 81 ClassLoader cl = cls.getClassLoader(); 82 if (cl == null) { 83 cl = getClassLoader(); 84 } 85 return cl; 86 } 87 88 /** 89 * Returns a fallback class loader. 90 * @return A class loader 91 */ getClassLoader()92 public static ClassLoader getClassLoader() { 93 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 94 if (cl == null) { 95 cl = ClassLoader.getSystemClassLoader(); 96 if (cl == null) { 97 // When this method is called for initializing a ICU4J class 98 // during bootstrap, cl might be still null (other than Android?). 99 // In this case, we want to use the bootstrap class loader. 100 cl = getBootstrapClassLoader(); 101 } 102 } 103 return cl; 104 } 105 } 106