< prev index next >

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

Print this page

  29 import java.io.InputStream;
  30 import java.lang.module.ModuleDescriptor;
  31 import java.lang.module.ModuleReference;
  32 import java.lang.module.ModuleReader;
  33 import java.lang.ref.SoftReference;
  34 import java.net.MalformedURLException;
  35 import java.net.URI;
  36 import java.net.URL;
  37 import java.nio.ByteBuffer;
  38 import java.security.CodeSigner;
  39 import java.security.CodeSource;
  40 import java.security.SecureClassLoader;
  41 import java.util.ArrayList;
  42 import java.util.Collections;
  43 import java.util.Enumeration;
  44 import java.util.Iterator;
  45 import java.util.List;
  46 import java.util.Map;
  47 import java.util.NoSuchElementException;
  48 import java.util.Optional;

  49 import java.util.concurrent.ConcurrentHashMap;
  50 import java.util.function.Function;
  51 import java.util.jar.Attributes;
  52 import java.util.jar.Manifest;
  53 import java.util.stream.Stream;
  54 
  55 import jdk.internal.access.SharedSecrets;

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

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






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

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


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

 559             // attempt to load class in module defined to this loader
 560             assert loadedModule.loader() == this;
 561             return findClassInModuleOrNull(loadedModule, cn);
 562         }
 563 
 564         // search class path
 565         if (hasClassPath()) {
 566             return findClassOnClassPathOrNull(cn);
 567         }
 568 
 569         return null;
 570     }
 571 
 572     /**
 573      * Loads the class with the specified binary name.
 574      */
 575     @Override
 576     protected Class<?> loadClass(String cn, boolean resolve)
 577         throws ClassNotFoundException
 578     {



 579         Class<?> c = loadClassOrNull(cn, resolve);
 580         if (c == null)

 581             throw new ClassNotFoundException(cn);


 582         return c;
 583     }
 584 
 585     /**
 586      * A variation of {@code loadClass} to load a class with the specified
 587      * binary name. This method returns {@code null} when the class is not
 588      * found.
 589      */
 590     protected Class<?> loadClassOrNull(String cn, boolean resolve) {
 591         synchronized (getClassLoadingLock(cn)) {
 592             // check if already loaded
 593             Class<?> c = findLoadedClass(cn);
 594 
 595             if (c == null) {
 596 
 597                 // find the candidate module for this class
 598                 LoadedModule loadedModule = findLoadedModule(cn);
 599                 if (loadedModule != null) {
 600 
 601                     // package is in a module

 968         ModuleDescriptor descriptor = mref.descriptor();
 969         if (descriptor.isOpen() || descriptor.isAutomatic())
 970             return true;
 971         for (ModuleDescriptor.Opens opens : descriptor.opens()) {
 972             String source = opens.source();
 973             if (!opens.isQualified() && source.equals(pn)) {
 974                 return true;
 975             }
 976         }
 977         return false;
 978     }
 979 
 980     // Called from VM only, during -Xshare:dump
 981     private void resetArchivedStates() {
 982         ucp = null;
 983         resourceCache = null;
 984         if (!moduleToReader.isEmpty()) {
 985             moduleToReader.clear();
 986         }
 987     }















































 988 }

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

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

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

 569             // attempt to load class in module defined to this loader
 570             assert loadedModule.loader() == this;
 571             return findClassInModuleOrNull(loadedModule, cn);
 572         }
 573 
 574         // search class path
 575         if (hasClassPath()) {
 576             return findClassOnClassPathOrNull(cn);
 577         }
 578 
 579         return null;
 580     }
 581 
 582     /**
 583      * Loads the class with the specified binary name.
 584      */
 585     @Override
 586     protected Class<?> loadClass(String cn, boolean resolve)
 587         throws ClassNotFoundException
 588     {
 589         if (useNegativeCache && checkNegativeLookupCache(cn)) {
 590             throw new ClassNotFoundException(cn);
 591         }
 592         Class<?> c = loadClassOrNull(cn, resolve);
 593         if (c == null) {
 594             addToNegativeLookupCache(cn);
 595             throw new ClassNotFoundException(cn);
 596         }
 597 
 598         return c;
 599     }
 600 
 601     /**
 602      * A variation of {@code loadClass} to load a class with the specified
 603      * binary name. This method returns {@code null} when the class is not
 604      * found.
 605      */
 606     protected Class<?> loadClassOrNull(String cn, boolean resolve) {
 607         synchronized (getClassLoadingLock(cn)) {
 608             // check if already loaded
 609             Class<?> c = findLoadedClass(cn);
 610 
 611             if (c == null) {
 612 
 613                 // find the candidate module for this class
 614                 LoadedModule loadedModule = findLoadedModule(cn);
 615                 if (loadedModule != null) {
 616 
 617                     // package is in a module

 984         ModuleDescriptor descriptor = mref.descriptor();
 985         if (descriptor.isOpen() || descriptor.isAutomatic())
 986             return true;
 987         for (ModuleDescriptor.Opens opens : descriptor.opens()) {
 988             String source = opens.source();
 989             if (!opens.isQualified() && source.equals(pn)) {
 990                 return true;
 991             }
 992         }
 993         return false;
 994     }
 995 
 996     // Called from VM only, during -Xshare:dump
 997     private void resetArchivedStates() {
 998         ucp = null;
 999         resourceCache = null;
1000         if (!moduleToReader.isEmpty()) {
1001             moduleToReader.clear();
1002         }
1003     }
1004 
1005     public boolean checkNegativeLookupCache(String className) {
1006         return negativeLookupCache.contains(className);
1007     }
1008 
1009     public void addToNegativeLookupCache(String className) {
1010         negativeLookupCache.add(className);
1011     }
1012 
1013     public String negativeLookupCacheContents() {
1014         String[] contents = negativeLookupCache.toArray(new String[]{});
1015         StringBuilder builder = new StringBuilder();
1016         if (contents.length != 0) {
1017             for (String name: contents) {
1018                 if (builder.length() != 0) {
1019                     builder.append(" ");
1020                 }
1021                 builder.append(name);
1022             }
1023             return builder.toString();
1024         } else {
1025             return null;
1026         }
1027     }
1028 
1029     public void generateNegativeLookupCache(String contents) {
1030         String[] tokens = contents.split(" ");
1031         if (tokens.length > 0) {
1032             for (String token : tokens) {
1033                 negativeLookupCache.add(token);
1034             }
1035             useNegativeCache = true;
1036         }
1037     }
1038 
1039     public Class<?> checkPositiveLookupCache(String className) {
1040         return positiveLookupCache.get(className);
1041     }
1042 
1043     public void generatePositiveLookupCache(Class<?>[] cls) {
1044         if (cls.length > 0) {
1045             for (Class<?> c : cls) {
1046                 positiveLookupCache.put(c.getName(), c);
1047             }
1048             usePositiveCache = true;
1049         }
1050     }
1051 }
< prev index next >