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