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;
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 void setClassPath(URLClassPath ucp) {
110 this.ucp = ucp;
111 }
112
113 /**
114 * A module defined/loaded by a built-in class loader.
115 *
116 * A LoadedModule encapsulates a ModuleReference along with its CodeSource
117 * URL to avoid needing to create this URL when defining classes.
118 */
119 private static class LoadedModule {
120 private final BuiltinClassLoader loader;
121 private final ModuleReference mref;
122 private final URI uri; // may be null
123 private @Stable URL codeSourceURL; // may be null
124
125 LoadedModule(BuiltinClassLoader loader, ModuleReference mref) {
126 URL url = null;
127 this.uri = mref.location().orElse(null);
128
129 // for non-jrt schemes we need to resolve the codeSourceURL
130 // eagerly during bootstrap since the handler might be
131 // overridden
142 String name() { return mref.descriptor().name(); }
143
144 URL codeSourceURL() {
145 URL url = codeSourceURL;
146 if (url == null && uri != null) {
147 codeSourceURL = url = createURL(uri);
148 }
149 return url;
150 }
151
152 private URL createURL(URI uri) {
153 URL url = null;
154 try {
155 url = uri.toURL();
156 } catch (MalformedURLException | IllegalArgumentException e) {
157 }
158 return url;
159 }
160 }
161
162 static class ArchivedData {
163 static Map<String, LoadedModule> packageToModule;
164 }
165
166 // maps package name to loaded module for modules in the boot layer
167 private static final Map<String, LoadedModule> packageToModule;
168
169 static {
170 VM.initializeFromArchive(ArchivedData.class);
171 if (ArchivedData.packageToModule != null) {
172 packageToModule = ArchivedData.packageToModule;
173 } else {
174 packageToModule = new ConcurrentHashMap<>(1024);
175 ArchivedData.packageToModule = packageToModule;
176 }
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;
1039 */
1040 private boolean isOpen(ModuleReference mref, String pn) {
1041 ModuleDescriptor descriptor = mref.descriptor();
1042 if (descriptor.isOpen() || descriptor.isAutomatic())
1043 return true;
1044 for (ModuleDescriptor.Opens opens : descriptor.opens()) {
1045 String source = opens.source();
1046 if (!opens.isQualified() && source.equals(pn)) {
1047 return true;
1048 }
1049 }
1050 return false;
1051 }
1052
1053 /**
1054 * Checks access to the given URL. We use URLClassPath for consistent
1055 * checking with java.net.URLClassLoader.
1056 */
1057 private static URL checkURL(URL url) {
1058 return URLClassPath.checkURL(url);
1059 }
1060
1061 // Called from VM only, during -Xshare:dump
1062 private void resetArchivedStates() {
1063 ucp = null;
1064 }
1065 }
|