< prev index next >

src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java

Print this page

  34 import java.net.MalformedURLException;
  35 import java.net.URI;
  36 import java.net.URL;
  37 import java.nio.ByteBuffer;
  38 import java.security.AccessController;
  39 import java.security.CodeSigner;
  40 import java.security.CodeSource;
  41 import java.security.PermissionCollection;
  42 import java.security.PrivilegedAction;
  43 import java.security.PrivilegedActionException;
  44 import java.security.PrivilegedExceptionAction;
  45 import java.security.SecureClassLoader;
  46 import java.util.ArrayList;
  47 import java.util.Collections;
  48 import java.util.Enumeration;
  49 import java.util.Iterator;
  50 import java.util.List;
  51 import java.util.Map;
  52 import java.util.NoSuchElementException;
  53 import java.util.Optional;

  54 import java.util.concurrent.ConcurrentHashMap;
  55 import java.util.function.Function;
  56 import java.util.jar.Attributes;
  57 import java.util.jar.Manifest;
  58 import java.util.stream.Stream;
  59 
  60 import jdk.internal.access.SharedSecrets;

  61 import jdk.internal.misc.VM;
  62 import jdk.internal.module.ModulePatcher.PatchedModuleReader;
  63 import jdk.internal.module.Resources;
  64 import jdk.internal.vm.annotation.Stable;
  65 import sun.security.util.LazyCodeSourcePermissionCollection;
  66 
  67 
  68 /**
  69  * The platform or application class loader. Resources loaded from modules
  70  * defined to the boot class loader are also loaded via an instance of this
  71  * ClassLoader type.
  72  *
  73  * <p> This ClassLoader supports loading of classes and resources from modules.
  74  * Modules are defined to the ClassLoader by invoking the {@link #loadModule}
  75  * method. Defining a module to this ClassLoader has the effect of making the
  76  * types in the module visible. </p>
  77  *
  78  * <p> This ClassLoader also supports loading of classes and resources from a
  79  * class path of URLs that are specified to the ClassLoader at construction
  80  * time. The class path may expand at runtime (the Class-Path attribute in JAR

  89  * found in the parent then it searches the class path. The main difference
  90  * between this and the usual delegation model is that it allows the platform
  91  * class loader to delegate to the application class loader, important with
  92  * upgraded modules defined to the platform class loader.
  93  */
  94 
  95 public class BuiltinClassLoader
  96     extends SecureClassLoader
  97 {
  98     static {
  99         if (!ClassLoader.registerAsParallelCapable())
 100             throw new InternalError("Unable to register as parallel capable");
 101     }
 102 
 103     // parent ClassLoader
 104     private final BuiltinClassLoader parent;
 105 
 106     // the URL class path, or null if there is no class path
 107     private @Stable URLClassPath ucp;
 108 






 109     /**
 110      * A module defined/loaded by a built-in class loader.
 111      *
 112      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
 113      * URL to avoid needing to create this URL when defining classes.
 114      */
 115     private static class LoadedModule {
 116         private final BuiltinClassLoader loader;
 117         private final ModuleReference mref;
 118         private final URI uri;                      // may be null
 119         private @Stable URL codeSourceURL;          // may be null
 120 
 121         LoadedModule(BuiltinClassLoader loader, ModuleReference mref) {
 122             URL url = null;
 123             this.uri = mref.location().orElse(null);
 124 
 125             // for non-jrt schemes we need to resolve the codeSourceURL
 126             // eagerly during bootstrap since the handler might be
 127             // overridden
 128             if (uri != null && !"jrt".equals(uri.getScheme())) {

 181 
 182     // maps a module reference to a module reader
 183     private final Map<ModuleReference, ModuleReader> moduleToReader;
 184 
 185     // cache of resource name -> list of URLs.
 186     // used only for resources that are not in module packages
 187     private volatile SoftReference<Map<String, List<URL>>> resourceCache;
 188 
 189     /**
 190      * Create a new instance.
 191      */
 192     BuiltinClassLoader(String name, BuiltinClassLoader parent, URLClassPath ucp) {
 193         // ensure getParent() returns null when the parent is the boot loader
 194         super(name, parent == null || parent == ClassLoaders.bootLoader() ? null : parent);
 195 
 196         this.parent = parent;
 197         this.ucp = ucp;
 198 
 199         this.nameToModule = new ConcurrentHashMap<>(32);
 200         this.moduleToReader = new ConcurrentHashMap<>();


 201     }
 202 
 203     /**
 204      * Appends to the given file path to the class path.
 205      */
 206     void appendClassPath(String path) {
 207         // assert ucp != null;
 208         ucp.addFile(path);
 209     }
 210 
 211     /**
 212      * Sets the class path, called to reset the class path during -Xshare:dump
 213      */
 214     void setClassPath(URLClassPath ucp) {
 215         this.ucp = ucp;
 216     }
 217 
 218     /**
 219      * Returns {@code true} if there is a class path associated with this
 220      * class loader.

 619             // attempt to load class in module defined to this loader
 620             assert loadedModule.loader() == this;
 621             return findClassInModuleOrNull(loadedModule, cn);
 622         }
 623 
 624         // search class path
 625         if (hasClassPath()) {
 626             return findClassOnClassPathOrNull(cn);
 627         }
 628 
 629         return null;
 630     }
 631 
 632     /**
 633      * Loads the class with the specified binary name.
 634      */
 635     @Override
 636     protected Class<?> loadClass(String cn, boolean resolve)
 637         throws ClassNotFoundException
 638     {



 639         Class<?> c = loadClassOrNull(cn, resolve);
 640         if (c == null)

 641             throw new ClassNotFoundException(cn);


 642         return c;
 643     }
 644 
 645     /**
 646      * A variation of {@code loadClass} to load a class with the specified
 647      * binary name. This method returns {@code null} when the class is not
 648      * found.
 649      */
 650     protected Class<?> loadClassOrNull(String cn, boolean resolve) {
 651         synchronized (getClassLoadingLock(cn)) {
 652             // check if already loaded
 653             Class<?> c = findLoadedClass(cn);
 654 
 655             if (c == null) {
 656 
 657                 // find the candidate module for this class
 658                 LoadedModule loadedModule = findLoadedModule(cn);
 659                 if (loadedModule != null) {
 660 
 661                     // package is in a module

1068             if (!opens.isQualified() && source.equals(pn)) {
1069                 return true;
1070             }
1071         }
1072         return false;
1073     }
1074 
1075     /**
1076      * Checks access to the given URL. We use URLClassPath for consistent
1077      * checking with java.net.URLClassLoader.
1078      */
1079     private static URL checkURL(URL url) {
1080         return URLClassPath.checkURL(url);
1081     }
1082 
1083     // Called from VM only, during -Xshare:dump
1084     private void resetArchivedStates() {
1085         ucp = null;
1086         resourceCache = null;
1087     }















































1088 }

  34 import java.net.MalformedURLException;
  35 import java.net.URI;
  36 import java.net.URL;
  37 import java.nio.ByteBuffer;
  38 import java.security.AccessController;
  39 import java.security.CodeSigner;
  40 import java.security.CodeSource;
  41 import java.security.PermissionCollection;
  42 import java.security.PrivilegedAction;
  43 import java.security.PrivilegedActionException;
  44 import java.security.PrivilegedExceptionAction;
  45 import java.security.SecureClassLoader;
  46 import java.util.ArrayList;
  47 import java.util.Collections;
  48 import java.util.Enumeration;
  49 import java.util.Iterator;
  50 import java.util.List;
  51 import java.util.Map;
  52 import java.util.NoSuchElementException;
  53 import java.util.Optional;
  54 import java.util.Set;
  55 import java.util.concurrent.ConcurrentHashMap;
  56 import java.util.function.Function;
  57 import java.util.jar.Attributes;
  58 import java.util.jar.Manifest;
  59 import java.util.stream.Stream;
  60 
  61 import jdk.internal.access.SharedSecrets;
  62 import jdk.internal.misc.CDS;
  63 import jdk.internal.misc.VM;
  64 import jdk.internal.module.ModulePatcher.PatchedModuleReader;
  65 import jdk.internal.module.Resources;
  66 import jdk.internal.vm.annotation.Stable;
  67 import sun.security.util.LazyCodeSourcePermissionCollection;
  68 
  69 
  70 /**
  71  * The platform or application class loader. Resources loaded from modules
  72  * defined to the boot class loader are also loaded via an instance of this
  73  * ClassLoader type.
  74  *
  75  * <p> This ClassLoader supports loading of classes and resources from modules.
  76  * Modules are defined to the ClassLoader by invoking the {@link #loadModule}
  77  * method. Defining a module to this ClassLoader has the effect of making the
  78  * types in the module visible. </p>
  79  *
  80  * <p> This ClassLoader also supports loading of classes and resources from a
  81  * class path of URLs that are specified to the ClassLoader at construction
  82  * time. The class path may expand at runtime (the Class-Path attribute in JAR

  91  * found in the parent then it searches the class path. The main difference
  92  * between this and the usual delegation model is that it allows the platform
  93  * class loader to delegate to the application class loader, important with
  94  * upgraded modules defined to the platform class loader.
  95  */
  96 
  97 public class BuiltinClassLoader
  98     extends SecureClassLoader
  99 {
 100     static {
 101         if (!ClassLoader.registerAsParallelCapable())
 102             throw new InternalError("Unable to register as parallel capable");
 103     }
 104 
 105     // parent ClassLoader
 106     private final BuiltinClassLoader parent;
 107 
 108     // the URL class path, or null if there is no class path
 109     private @Stable URLClassPath ucp;
 110 
 111     private Set<String> negativeLookupCache;
 112     private Map<String, Class<? extends Object>> positiveLookupCache;
 113 
 114     public boolean useNegativeCache = false;
 115     public boolean usePositiveCache = false;
 116 
 117     /**
 118      * A module defined/loaded by a built-in class loader.
 119      *
 120      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
 121      * URL to avoid needing to create this URL when defining classes.
 122      */
 123     private static class LoadedModule {
 124         private final BuiltinClassLoader loader;
 125         private final ModuleReference mref;
 126         private final URI uri;                      // may be null
 127         private @Stable URL codeSourceURL;          // may be null
 128 
 129         LoadedModule(BuiltinClassLoader loader, ModuleReference mref) {
 130             URL url = null;
 131             this.uri = mref.location().orElse(null);
 132 
 133             // for non-jrt schemes we need to resolve the codeSourceURL
 134             // eagerly during bootstrap since the handler might be
 135             // overridden
 136             if (uri != null && !"jrt".equals(uri.getScheme())) {

 189 
 190     // maps a module reference to a module reader
 191     private final Map<ModuleReference, ModuleReader> moduleToReader;
 192 
 193     // cache of resource name -> list of URLs.
 194     // used only for resources that are not in module packages
 195     private volatile SoftReference<Map<String, List<URL>>> resourceCache;
 196 
 197     /**
 198      * Create a new instance.
 199      */
 200     BuiltinClassLoader(String name, BuiltinClassLoader parent, URLClassPath ucp) {
 201         // ensure getParent() returns null when the parent is the boot loader
 202         super(name, parent == null || parent == ClassLoaders.bootLoader() ? null : parent);
 203 
 204         this.parent = parent;
 205         this.ucp = ucp;
 206 
 207         this.nameToModule = new ConcurrentHashMap<>(32);
 208         this.moduleToReader = new ConcurrentHashMap<>();
 209         this.negativeLookupCache = ConcurrentHashMap.newKeySet();
 210         this.positiveLookupCache = new ConcurrentHashMap<>();
 211     }
 212 
 213     /**
 214      * Appends to the given file path to the class path.
 215      */
 216     void appendClassPath(String path) {
 217         // assert ucp != null;
 218         ucp.addFile(path);
 219     }
 220 
 221     /**
 222      * Sets the class path, called to reset the class path during -Xshare:dump
 223      */
 224     void setClassPath(URLClassPath ucp) {
 225         this.ucp = ucp;
 226     }
 227 
 228     /**
 229      * Returns {@code true} if there is a class path associated with this
 230      * class loader.

 629             // attempt to load class in module defined to this loader
 630             assert loadedModule.loader() == this;
 631             return findClassInModuleOrNull(loadedModule, cn);
 632         }
 633 
 634         // search class path
 635         if (hasClassPath()) {
 636             return findClassOnClassPathOrNull(cn);
 637         }
 638 
 639         return null;
 640     }
 641 
 642     /**
 643      * Loads the class with the specified binary name.
 644      */
 645     @Override
 646     protected Class<?> loadClass(String cn, boolean resolve)
 647         throws ClassNotFoundException
 648     {
 649         if (useNegativeCache && checkNegativeLookupCache(cn)) {
 650             throw new ClassNotFoundException(cn);
 651         }
 652         Class<?> c = loadClassOrNull(cn, resolve);
 653         if (c == null) {
 654             addToNegativeLookupCache(cn);
 655             throw new ClassNotFoundException(cn);
 656         }
 657 
 658         return c;
 659     }
 660 
 661     /**
 662      * A variation of {@code loadClass} to load a class with the specified
 663      * binary name. This method returns {@code null} when the class is not
 664      * found.
 665      */
 666     protected Class<?> loadClassOrNull(String cn, boolean resolve) {
 667         synchronized (getClassLoadingLock(cn)) {
 668             // check if already loaded
 669             Class<?> c = findLoadedClass(cn);
 670 
 671             if (c == null) {
 672 
 673                 // find the candidate module for this class
 674                 LoadedModule loadedModule = findLoadedModule(cn);
 675                 if (loadedModule != null) {
 676 
 677                     // package is in a module

1084             if (!opens.isQualified() && source.equals(pn)) {
1085                 return true;
1086             }
1087         }
1088         return false;
1089     }
1090 
1091     /**
1092      * Checks access to the given URL. We use URLClassPath for consistent
1093      * checking with java.net.URLClassLoader.
1094      */
1095     private static URL checkURL(URL url) {
1096         return URLClassPath.checkURL(url);
1097     }
1098 
1099     // Called from VM only, during -Xshare:dump
1100     private void resetArchivedStates() {
1101         ucp = null;
1102         resourceCache = null;
1103     }
1104 
1105     public boolean checkNegativeLookupCache(String className) {
1106         return negativeLookupCache.contains(className);
1107     }
1108 
1109     public void addToNegativeLookupCache(String className) {
1110         negativeLookupCache.add(className);
1111     }
1112 
1113     public String negativeLookupCacheContents() {
1114         String[] contents = negativeLookupCache.toArray(new String[]{});
1115         StringBuilder builder = new StringBuilder();
1116         if (contents.length != 0) {
1117             for (String name: contents) {
1118                 if (builder.length() != 0) {
1119                     builder.append(" ");
1120                 }
1121                 builder.append(name);
1122             }
1123             return builder.toString();
1124         } else {
1125             return null;
1126         }
1127     }
1128 
1129     public void generateNegativeLookupCache(String contents) {
1130         String[] tokens = contents.split(" ");
1131         if (tokens.length > 0) {
1132             for (String token : tokens) {
1133                 negativeLookupCache.add(token);
1134             }
1135             useNegativeCache = true;
1136         }
1137     }
1138 
1139     public Class<?> checkPositiveLookupCache(String className) {
1140         return positiveLookupCache.get(className);
1141     }
1142 
1143     public void generatePositiveLookupCache(Class<?>[] cls) {
1144         if (cls.length > 0) {
1145             for (Class<?> c : cls) {
1146                 positiveLookupCache.put(c.getName(), c);
1147             }
1148             usePositiveCache = true;
1149         }
1150     }
1151 }
< prev index next >