< prev index next >

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

Print this page


  87  * directly to that class loader. If there isn't a module containing the
  88  * package then it delegates the search to the parent class loader and if not
  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 final URLClassPath ucp;
 108 
 109 
 110     /**
 111      * A module defined/loaded by a built-in class loader.
 112      *
 113      * A LoadedModule encapsulates a ModuleReference along with its CodeSource
 114      * URL to avoid needing to create this URL when defining classes.
 115      */
 116     private static class LoadedModule {
 117         private final BuiltinClassLoader loader;
 118         private final ModuleReference mref;
 119         private final URI uri;                      // may be null
 120         private @Stable URL codeSourceURL;          // may be null
 121 
 122         LoadedModule(BuiltinClassLoader loader, ModuleReference mref) {
 123             URL url = null;
 124             this.uri = mref.location().orElse(null);
 125 
 126             // for non-jrt schemes we need to resolve the codeSourceURL
 127             // eagerly during bootstrap since the handler might be
 128             // overridden


 139         String name() { return mref.descriptor().name(); }
 140 
 141         URL codeSourceURL() {
 142             URL url = codeSourceURL;
 143             if (url == null && uri != null) {
 144                 codeSourceURL = url = createURL(uri);
 145             }
 146             return url;
 147         }
 148 
 149         private URL createURL(URI uri) {
 150             URL url = null;
 151             try {
 152                 url = uri.toURL();
 153             } catch (MalformedURLException | IllegalArgumentException e) {
 154             }
 155             return url;
 156         }
 157     }
 158 
 159 
 160     // maps package name to loaded module for modules in the boot layer
 161     private static final Map<String, LoadedModule> packageToModule
 162         = new ConcurrentHashMap<>(1024);

















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















 189      * Returns {@code true} if there is a class path associated with this
 190      * class loader.
 191      */
 192     boolean hasClassPath() {
 193         return ucp != null;
 194     }
 195 
 196     /**
 197      * Register a module this class loader. This has the effect of making the
 198      * types in the module visible.
 199      */
 200     public void loadModule(ModuleReference mref) {
 201         ModuleDescriptor descriptor = mref.descriptor();
 202         String mn = descriptor.name();
 203         if (nameToModule.putIfAbsent(mn, mref) != null) {
 204             throw new InternalError(mn + " already defined to this loader");
 205         }
 206 
 207         LoadedModule loadedModule = new LoadedModule(this, mref);
 208         for (String pn : descriptor.packages()) {


1024      */
1025     private boolean isOpen(ModuleReference mref, String pn) {
1026         ModuleDescriptor descriptor = mref.descriptor();
1027         if (descriptor.isOpen() || descriptor.isAutomatic())
1028             return true;
1029         for (ModuleDescriptor.Opens opens : descriptor.opens()) {
1030             String source = opens.source();
1031             if (!opens.isQualified() && source.equals(pn)) {
1032                 return true;
1033             }
1034         }
1035         return false;
1036     }
1037 
1038     /**
1039      * Checks access to the given URL. We use URLClassPath for consistent
1040      * checking with java.net.URLClassLoader.
1041      */
1042     private static URL checkURL(URL url) {
1043         return URLClassPath.checkURL(url);





1044     }
1045 }


  87  * directly to that class loader. If there isn't a module containing the
  88  * package then it delegates the search to the parent class loader and if not
  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


 138         String name() { return mref.descriptor().name(); }
 139 
 140         URL codeSourceURL() {
 141             URL url = codeSourceURL;
 142             if (url == null && uri != null) {
 143                 codeSourceURL = url = createURL(uri);
 144             }
 145             return url;
 146         }
 147 
 148         private URL createURL(URI uri) {
 149             URL url = null;
 150             try {
 151                 url = uri.toURL();
 152             } catch (MalformedURLException | IllegalArgumentException e) {
 153             }
 154             return url;
 155         }
 156     }
 157 

 158     // maps package name to loaded module for modules in the boot layer
 159     private static final Map<String, LoadedModule> packageToModule;
 160     static {
 161         ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
 162         if (archivedClassLoaders != null) {
 163             @SuppressWarnings("unchecked")
 164             Map<String, LoadedModule> map
 165                 = (Map<String, LoadedModule>) archivedClassLoaders.packageToModule();
 166             packageToModule = map;
 167         } else {
 168             packageToModule = new ConcurrentHashMap<>(1024);
 169         }
 170     }
 171 
 172     /**
 173      * Invoked by ArchivedClassLoaders to archive the package-to-module map.
 174      */
 175     static Map<String, ?> packageToModule() {
 176         return packageToModule;
 177     }
 178 
 179     // maps a module name to a module reference
 180     private final Map<String, ModuleReference> nameToModule;
 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.
 221      */
 222     boolean hasClassPath() {
 223         return ucp != null;
 224     }
 225 
 226     /**
 227      * Register a module this class loader. This has the effect of making the
 228      * types in the module visible.
 229      */
 230     public void loadModule(ModuleReference mref) {
 231         ModuleDescriptor descriptor = mref.descriptor();
 232         String mn = descriptor.name();
 233         if (nameToModule.putIfAbsent(mn, mref) != null) {
 234             throw new InternalError(mn + " already defined to this loader");
 235         }
 236 
 237         LoadedModule loadedModule = new LoadedModule(this, mref);
 238         for (String pn : descriptor.packages()) {


1054      */
1055     private boolean isOpen(ModuleReference mref, String pn) {
1056         ModuleDescriptor descriptor = mref.descriptor();
1057         if (descriptor.isOpen() || descriptor.isAutomatic())
1058             return true;
1059         for (ModuleDescriptor.Opens opens : descriptor.opens()) {
1060             String source = opens.source();
1061             if (!opens.isQualified() && source.equals(pn)) {
1062                 return true;
1063             }
1064         }
1065         return false;
1066     }
1067 
1068     /**
1069      * Checks access to the given URL. We use URLClassPath for consistent
1070      * checking with java.net.URLClassLoader.
1071      */
1072     private static URL checkURL(URL url) {
1073         return URLClassPath.checkURL(url);
1074     }
1075 
1076     // Called from VM only, during -Xshare:dump
1077     private void resetArchivedStates() {
1078         ucp = null;
1079     }
1080 }
< prev index next >