43 import java.security.CodeSigner;
44 import java.security.CodeSource;
45 import java.security.Permission;
46 import java.security.PermissionCollection;
47 import java.security.PrivilegedAction;
48 import java.security.PrivilegedActionException;
49 import java.security.PrivilegedExceptionAction;
50 import java.security.SecureClassLoader;
51 import java.util.ArrayList;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.Enumeration;
55 import java.util.HashMap;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Optional;
59 import java.util.concurrent.ConcurrentHashMap;
60 import java.util.stream.Stream;
61
62 import jdk.internal.misc.SharedSecrets;
63
64
65 /**
66 * A class loader that loads classes and resources from a collection of
67 * modules, or from a single module where the class loader is a member
68 * of a pool of class loaders.
69 *
70 * <p> The delegation model used by this ClassLoader differs to the regular
71 * delegation model. When requested to load a class then this ClassLoader first
72 * maps the class name to its package name. If there a module defined to the
73 * Loader containing the package then the class loader attempts to load from
74 * that module. If the package is instead defined to a module in a "remote"
75 * ClassLoader then this class loader delegates directly to that class loader.
76 * The map of package name to remote class loader is created based on the
77 * modules read by modules defined to this class loader. If the package is not
78 * local or remote then this class loader will delegate to the parent class
79 * loader. This allows automatic modules (for example) to link to types in the
80 * unnamed module of the parent class loader.
81 *
82 * @see Layer#defineModulesWithOneLoader
339 if (url != null && System.getSecurityManager() != null) {
340 try {
341 URL urlToCheck = url;
342 url = AccessController.doPrivileged(
343 new PrivilegedExceptionAction<URL>() {
344 @Override
345 public URL run() throws IOException {
346 return URLClassPath.checkURL(urlToCheck);
347 }
348 }, acc);
349 } catch (PrivilegedActionException pae) {
350 url = null;
351 }
352 }
353
354 return url;
355 }
356
357 @Override
358 public URL findResource(String name) {
359 URL url = null;
360 String pn = ResourceHelper.getPackageName(name);
361 LoadedModule module = localPackageToModule.get(pn);
362 if (module != null) {
363 if (name.endsWith(".class") || isOpen(module.mref(), pn)) {
364 try {
365 url = findResource(module.name(), name);
366 } catch (IOException ioe) {
367 // ignore
368 }
369 }
370 } else {
371 for (ModuleReference mref : nameToModule.values()) {
372 try {
373 url = findResource(mref.descriptor().name(), name);
374 if (url != null)
375 break;
376 } catch (IOException ioe) {
377 // ignore
378 }
379 }
380 }
381 return url;
382 }
383
384 @Override
385 public Enumeration<URL> findResources(String name) throws IOException {
386 List<URL> urls = new ArrayList<>();
387 String pn = ResourceHelper.getPackageName(name);
388 LoadedModule module = localPackageToModule.get(pn);
389 if (module != null) {
390 if (name.endsWith(".class") || isOpen(module.mref(), pn)) {
391 try {
392 URL url = findResource(module.name(), name);
393 if (url != null)
394 urls.add(url);
395 } catch (IOException ioe) {
396 // ignore
397 }
398 }
399 } else {
400 for (ModuleReference mref : nameToModule.values()) {
401 try {
402 URL url = findResource(mref.descriptor().name(), name);
403 if (url != null)
404 urls.add(url);
405 } catch (IOException ioe) {
406 // ignore
407 }
408 }
409 }
410 return Collections.enumeration(urls);
411 }
412
413
414 // -- finding/loading classes
415
416 /**
417 * Finds the class with the specified binary name.
418 */
626 @Override
627 public Stream<String> list() {
628 return Stream.empty();
629 }
630 @Override
631 public void close() {
632 throw new InternalError("Should not get here");
633 }
634 }
635
636 /**
637 * Returns true if the given module opens the given package
638 * unconditionally.
639 *
640 * @implNote This method currently iterates over each of the open
641 * packages. This will be replaced once the ModuleDescriptor.Opens
642 * API is updated.
643 */
644 private boolean isOpen(ModuleReference mref, String pn) {
645 ModuleDescriptor descriptor = mref.descriptor();
646 if (descriptor.isOpen())
647 return true;
648 for (ModuleDescriptor.Opens opens : descriptor.opens()) {
649 String source = opens.source();
650 if (!opens.isQualified() && source.equals(pn)) {
651 return true;
652 }
653 }
654 return false;
655 }
656 }
|
43 import java.security.CodeSigner;
44 import java.security.CodeSource;
45 import java.security.Permission;
46 import java.security.PermissionCollection;
47 import java.security.PrivilegedAction;
48 import java.security.PrivilegedActionException;
49 import java.security.PrivilegedExceptionAction;
50 import java.security.SecureClassLoader;
51 import java.util.ArrayList;
52 import java.util.Collection;
53 import java.util.Collections;
54 import java.util.Enumeration;
55 import java.util.HashMap;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Optional;
59 import java.util.concurrent.ConcurrentHashMap;
60 import java.util.stream.Stream;
61
62 import jdk.internal.misc.SharedSecrets;
63 import jdk.internal.module.Resources;
64
65
66 /**
67 * A class loader that loads classes and resources from a collection of
68 * modules, or from a single module where the class loader is a member
69 * of a pool of class loaders.
70 *
71 * <p> The delegation model used by this ClassLoader differs to the regular
72 * delegation model. When requested to load a class then this ClassLoader first
73 * maps the class name to its package name. If there a module defined to the
74 * Loader containing the package then the class loader attempts to load from
75 * that module. If the package is instead defined to a module in a "remote"
76 * ClassLoader then this class loader delegates directly to that class loader.
77 * The map of package name to remote class loader is created based on the
78 * modules read by modules defined to this class loader. If the package is not
79 * local or remote then this class loader will delegate to the parent class
80 * loader. This allows automatic modules (for example) to link to types in the
81 * unnamed module of the parent class loader.
82 *
83 * @see Layer#defineModulesWithOneLoader
340 if (url != null && System.getSecurityManager() != null) {
341 try {
342 URL urlToCheck = url;
343 url = AccessController.doPrivileged(
344 new PrivilegedExceptionAction<URL>() {
345 @Override
346 public URL run() throws IOException {
347 return URLClassPath.checkURL(urlToCheck);
348 }
349 }, acc);
350 } catch (PrivilegedActionException pae) {
351 url = null;
352 }
353 }
354
355 return url;
356 }
357
358 @Override
359 public URL findResource(String name) {
360 String pn = Resources.toPackageName(name);
361 LoadedModule module = localPackageToModule.get(pn);
362
363 if (module != null) {
364 try {
365 URL url = findResource(module.name(), name);
366 if (url != null
367 && (name.endsWith(".class")
368 || url.toString().endsWith("/")
369 || isOpen(module.mref(), pn))) {
370 return url;
371 }
372 } catch (IOException ioe) {
373 // ignore
374 }
375
376 } else {
377 for (ModuleReference mref : nameToModule.values()) {
378 try {
379 URL url = findResource(mref.descriptor().name(), name);
380 if (url != null) return url;
381 } catch (IOException ioe) {
382 // ignore
383 }
384 }
385 }
386
387 return null;
388 }
389
390 @Override
391 public Enumeration<URL> findResources(String name) throws IOException {
392 List<URL> urls = new ArrayList<>();
393 String pn = Resources.toPackageName(name);
394 LoadedModule module = localPackageToModule.get(pn);
395 if (module != null) {
396 try {
397 URL url = findResource(module.name(), name);
398 if (url != null
399 && (name.endsWith(".class")
400 || url.toString().endsWith("/")
401 || isOpen(module.mref(), pn))) {
402 urls.add(url);
403 }
404 } catch (IOException ioe) {
405 // ignore
406 }
407 } else {
408 for (ModuleReference mref : nameToModule.values()) {
409 try {
410 URL url = findResource(mref.descriptor().name(), name);
411 if (url != null)
412 urls.add(url);
413 } catch (IOException ioe) {
414 // ignore
415 }
416 }
417 }
418 return Collections.enumeration(urls);
419 }
420
421
422 // -- finding/loading classes
423
424 /**
425 * Finds the class with the specified binary name.
426 */
634 @Override
635 public Stream<String> list() {
636 return Stream.empty();
637 }
638 @Override
639 public void close() {
640 throw new InternalError("Should not get here");
641 }
642 }
643
644 /**
645 * Returns true if the given module opens the given package
646 * unconditionally.
647 *
648 * @implNote This method currently iterates over each of the open
649 * packages. This will be replaced once the ModuleDescriptor.Opens
650 * API is updated.
651 */
652 private boolean isOpen(ModuleReference mref, String pn) {
653 ModuleDescriptor descriptor = mref.descriptor();
654 if (descriptor.isOpen() || descriptor.isAutomatic())
655 return true;
656 for (ModuleDescriptor.Opens opens : descriptor.opens()) {
657 String source = opens.source();
658 if (!opens.isQualified() && source.equals(pn)) {
659 return true;
660 }
661 }
662 return false;
663 }
664 }
|