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