100
101 // maps a module reference to a module reader, populated lazily
102 private final Map<ModuleReference, ModuleReader> moduleToReader
103 = new ConcurrentHashMap<>();
104
105 // ACC used when loading classes and resources */
106 private final AccessControlContext acc;
107
108 /**
109 * A module defined/loaded to a {@code Loader}.
110 */
111 private static class LoadedModule {
112 private final ModuleReference mref;
113 private final URL url; // may be null
114 private final CodeSource cs;
115
116 LoadedModule(ModuleReference mref) {
117 URL url = null;
118 if (mref.location().isPresent()) {
119 try {
120 url = mref.location().get().toURL();
121 } catch (MalformedURLException e) { }
122 }
123 this.mref = mref;
124 this.url = url;
125 this.cs = new CodeSource(url, (CodeSigner[]) null);
126 }
127
128 ModuleReference mref() { return mref; }
129 String name() { return mref.descriptor().name(); }
130 URL location() { return url; }
131 CodeSource codeSource() { return cs; }
132 }
133
134
135 /**
136 * Creates a {@code Loader} in a loader pool that loads classes/resources
137 * from one module.
138 */
139 public Loader(ResolvedModule resolvedModule,
140 LoaderPool pool,
188 this.localPackageToModule = localPackageToModule;
189
190 this.acc = AccessController.getContext();
191 }
192
193
194 /**
195 * Completes initialization of this Loader. This method populates
196 * remotePackageToLoader with the packages of the remote modules, where
197 * "remote modules" are the modules read by modules defined to this loader.
198 *
199 * @param cf the Configuration containing at least modules to be defined to
200 * this class loader
201 *
202 * @param parentLayer the parent Layer
203 */
204 public Loader initRemotePackageMap(Configuration cf, Layer parentLayer) {
205
206 for (String name : nameToModule.keySet()) {
207
208 ResolvedModule resolvedModule = cf.findModule(name).get();
209 assert resolvedModule.configuration() == cf;
210
211 for (ResolvedModule other : resolvedModule.reads()) {
212 String mn = other.name();
213 ClassLoader loader;
214
215 if (other.configuration() == cf) {
216
217 // The module reads another module in the newly created
218 // layer. If all modules are defined to the same class
219 // loader then the packages are local.
220 if (pool == null) {
221 assert nameToModule.containsKey(mn);
222 continue;
223 }
224
225 loader = pool.loaderFor(mn);
226 assert loader != null;
227
228 } else {
290
291
292 /**
293 * Returns a URL to a resource of the given name in a module defined to
294 * this class loader.
295 */
296 @Override
297 protected URL findResource(String mn, String name) throws IOException {
298 ModuleReference mref = nameToModule.get(mn);
299 if (mref == null)
300 return null; // not defined to this class loader
301
302 try {
303 return AccessController.doPrivileged(
304 new PrivilegedExceptionAction<URL>() {
305 @Override
306 public URL run() throws IOException {
307 Optional<URI> ouri = moduleReaderFor(mref).find(name);
308 if (ouri.isPresent()) {
309 try {
310 return ouri.get().toURL();
311 } catch (MalformedURLException e) { }
312 }
313 return null;
314 }
315 }, acc);
316 } catch (PrivilegedActionException pae) {
317 throw (IOException) pae.getCause();
318 }
319 }
320
321
322 // -- finding/loading classes
323
324 /**
325 * Finds the class with the specified binary name.
326 */
327 @Override
328 protected Class<?> findClass(String cn) throws ClassNotFoundException {
329 Class<?> c = null;
330 LoadedModule loadedModule = findLoadedModule(cn);
|
100
101 // maps a module reference to a module reader, populated lazily
102 private final Map<ModuleReference, ModuleReader> moduleToReader
103 = new ConcurrentHashMap<>();
104
105 // ACC used when loading classes and resources */
106 private final AccessControlContext acc;
107
108 /**
109 * A module defined/loaded to a {@code Loader}.
110 */
111 private static class LoadedModule {
112 private final ModuleReference mref;
113 private final URL url; // may be null
114 private final CodeSource cs;
115
116 LoadedModule(ModuleReference mref) {
117 URL url = null;
118 if (mref.location().isPresent()) {
119 try {
120 url = mref.location().getWhenPresent().toURL();
121 } catch (MalformedURLException e) { }
122 }
123 this.mref = mref;
124 this.url = url;
125 this.cs = new CodeSource(url, (CodeSigner[]) null);
126 }
127
128 ModuleReference mref() { return mref; }
129 String name() { return mref.descriptor().name(); }
130 URL location() { return url; }
131 CodeSource codeSource() { return cs; }
132 }
133
134
135 /**
136 * Creates a {@code Loader} in a loader pool that loads classes/resources
137 * from one module.
138 */
139 public Loader(ResolvedModule resolvedModule,
140 LoaderPool pool,
188 this.localPackageToModule = localPackageToModule;
189
190 this.acc = AccessController.getContext();
191 }
192
193
194 /**
195 * Completes initialization of this Loader. This method populates
196 * remotePackageToLoader with the packages of the remote modules, where
197 * "remote modules" are the modules read by modules defined to this loader.
198 *
199 * @param cf the Configuration containing at least modules to be defined to
200 * this class loader
201 *
202 * @param parentLayer the parent Layer
203 */
204 public Loader initRemotePackageMap(Configuration cf, Layer parentLayer) {
205
206 for (String name : nameToModule.keySet()) {
207
208 ResolvedModule resolvedModule = cf.findModule(name).getWhenPresent();
209 assert resolvedModule.configuration() == cf;
210
211 for (ResolvedModule other : resolvedModule.reads()) {
212 String mn = other.name();
213 ClassLoader loader;
214
215 if (other.configuration() == cf) {
216
217 // The module reads another module in the newly created
218 // layer. If all modules are defined to the same class
219 // loader then the packages are local.
220 if (pool == null) {
221 assert nameToModule.containsKey(mn);
222 continue;
223 }
224
225 loader = pool.loaderFor(mn);
226 assert loader != null;
227
228 } else {
290
291
292 /**
293 * Returns a URL to a resource of the given name in a module defined to
294 * this class loader.
295 */
296 @Override
297 protected URL findResource(String mn, String name) throws IOException {
298 ModuleReference mref = nameToModule.get(mn);
299 if (mref == null)
300 return null; // not defined to this class loader
301
302 try {
303 return AccessController.doPrivileged(
304 new PrivilegedExceptionAction<URL>() {
305 @Override
306 public URL run() throws IOException {
307 Optional<URI> ouri = moduleReaderFor(mref).find(name);
308 if (ouri.isPresent()) {
309 try {
310 return ouri.getWhenPresent().toURL();
311 } catch (MalformedURLException e) { }
312 }
313 return null;
314 }
315 }, acc);
316 } catch (PrivilegedActionException pae) {
317 throw (IOException) pae.getCause();
318 }
319 }
320
321
322 // -- finding/loading classes
323
324 /**
325 * Finds the class with the specified binary name.
326 */
327 @Override
328 protected Class<?> findClass(String cn) throws ClassNotFoundException {
329 Class<?> c = null;
330 LoadedModule loadedModule = findLoadedModule(cn);
|