< prev index next >

src/java.base/share/classes/java/lang/reflect/Module.java

Print this page

        

*** 37,63 **** import java.lang.module.ResolvedModule; import java.net.URI; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.stream.Stream; import jdk.internal.loader.BuiltinClassLoader; import jdk.internal.loader.BootLoader; - import jdk.internal.loader.ResourceHelper; import jdk.internal.misc.JavaLangAccess; import jdk.internal.misc.JavaLangReflectModuleAccess; import jdk.internal.misc.SharedSecrets; import jdk.internal.module.ServicesCatalog; import jdk.internal.org.objectweb.asm.AnnotationVisitor; import jdk.internal.org.objectweb.asm.Attribute; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter; --- 37,65 ---- import java.lang.module.ResolvedModule; import java.net.URI; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedAction; + import java.util.Collections; import java.util.HashMap; import java.util.HashSet; + import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.stream.Stream; import jdk.internal.loader.BuiltinClassLoader; import jdk.internal.loader.BootLoader; import jdk.internal.misc.JavaLangAccess; import jdk.internal.misc.JavaLangReflectModuleAccess; import jdk.internal.misc.SharedSecrets; import jdk.internal.module.ServicesCatalog; + import jdk.internal.module.Resources; import jdk.internal.org.objectweb.asm.AnnotationVisitor; import jdk.internal.org.objectweb.asm.Attribute; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter;
*** 367,387 **** * Makes the given {@code Module} readable to this module. * * If {@code syncVM} is {@code true} then the VM is notified. */ private void implAddReads(Module other, boolean syncVM) { ! Objects.requireNonNull(other); ! ! // nothing to do ! if (other == this || !this.isNamed()) ! return; ! ! // check if we already read this module ! Set<Module> reads = this.reads; ! if (reads != null && reads.contains(other)) ! return; ! // update VM first, just in case it fails if (syncVM) { if (other == ALL_UNNAMED_MODULE) { addReads0(this, null); } else { --- 369,379 ---- * Makes the given {@code Module} readable to this module. * * If {@code syncVM} is {@code true} then the VM is notified. */ private void implAddReads(Module other, boolean syncVM) { ! if (!canRead(other)) { // update VM first, just in case it fails if (syncVM) { if (other == ALL_UNNAMED_MODULE) { addReads0(this, null); } else {
*** 390,399 **** --- 382,392 ---- } // add reflective read reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE); } + } // -- exported and open packages -- // the packages are open to other modules, can be null
*** 551,561 **** /** * Returns {@code true} if this module exports or opens a package to * the given module via its module declaration. */ ! boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) { // package is open to everyone or <other> Map<String, Set<Module>> openPackages = this.openPackages; if (openPackages != null) { Set<Module> targets = openPackages.get(pn); if (targets != null) { --- 544,554 ---- /** * Returns {@code true} if this module exports or opens a package to * the given module via its module declaration. */ ! private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) { // package is open to everyone or <other> Map<String, Set<Module>> openPackages = this.openPackages; if (openPackages != null) { Set<Module> targets = openPackages.get(pn); if (targets != null) {
*** 907,919 **** /** * Returns an array of the package names of the packages in this module. * * <p> For named modules, the returned array contains an element for each ! * package in the module. It may contain elements corresponding to packages ! * added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a> ! * for example, after it was loaded. * * <p> For unnamed modules, this method is the equivalent to invoking the * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of * this module's class loader and returning the array of package names. </p> * --- 900,910 ---- /** * Returns an array of the package names of the packages in this module. * * <p> For named modules, the returned array contains an element for each ! * package in the module. </p> * * <p> For unnamed modules, this method is the equivalent to invoking the * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of * this module's class loader and returning the array of package names. </p> *
*** 948,966 **** return packages.map(Package::getName).toArray(String[]::new); } } /** - * Add a package to this module. - * - * @apiNote This method is for Proxy use. - */ - void addPackage(String pn) { - implAddPackage(pn, true); - } - - /** * Add a package to this module without notifying the VM. * * @apiNote This method is VM white-box testing. */ void implAddPackageNoSync(String pn) { --- 939,948 ----
*** 1078,1101 **** Module m = nameToModule.get(mn); assert m != null; // reads Set<Module> reads = new HashSet<>(); for (ResolvedModule other : resolvedModule.reads()) { Module m2 = null; if (other.configuration() == cf) { ! String dn = other.reference().descriptor().name(); ! m2 = nameToModule.get(dn); } else { for (Layer parent: layer.parents()) { m2 = findModule(parent, other); if (m2 != null) break; } - } assert m2 != null; ! reads.add(m2); // update VM view addReads0(m, m2); } --- 1060,1091 ---- Module m = nameToModule.get(mn); assert m != null; // reads Set<Module> reads = new HashSet<>(); + + // name -> source Module when in parent layer + Map<String, Module> nameToSource = Collections.emptyMap(); + for (ResolvedModule other : resolvedModule.reads()) { Module m2 = null; if (other.configuration() == cf) { ! // this configuration ! m2 = nameToModule.get(other.name()); ! assert m2 != null; } else { + // parent layer for (Layer parent: layer.parents()) { m2 = findModule(parent, other); if (m2 != null) break; } assert m2 != null; ! if (nameToSource.isEmpty()) ! nameToSource = new HashMap<>(); ! nameToSource.put(other.name(), m2); ! } reads.add(m2); // update VM view addReads0(m, m2); }
*** 1105,1115 **** if (descriptor.isAutomatic()) { m.implAddReads(ALL_UNNAMED_MODULE, true); } // exports and opens ! initExportsAndOpens(descriptor, nameToModule, m); } // register the modules in the boot layer if (isBootLayer) { for (ResolvedModule resolvedModule : cf.modules()) { --- 1095,1105 ---- if (descriptor.isAutomatic()) { m.implAddReads(ALL_UNNAMED_MODULE, true); } // exports and opens ! initExportsAndOpens(m, nameToSource, nameToModule, layer.parents()); } // register the modules in the boot layer if (isBootLayer) { for (ResolvedModule resolvedModule : cf.modules()) {
*** 1157,1175 **** return m; }) .orElse(null); } /** * Initialize the maps of exported and open packages for module m. */ ! private static void initExportsAndOpens(ModuleDescriptor descriptor, Map<String, Module> nameToModule, ! Module m) ! { // The VM doesn't special case open or automatic modules so need to // export all packages if (descriptor.isOpen() || descriptor.isAutomatic()) { assert descriptor.opens().isEmpty(); for (String source : descriptor.packages()) { addExportsToAll0(m, source); } --- 1147,1167 ---- return m; }) .orElse(null); } + /** * Initialize the maps of exported and open packages for module m. */ ! private static void initExportsAndOpens(Module m, ! Map<String, Module> nameToSource, Map<String, Module> nameToModule, ! List<Layer> parents) { // The VM doesn't special case open or automatic modules so need to // export all packages + ModuleDescriptor descriptor = m.getDescriptor(); if (descriptor.isOpen() || descriptor.isAutomatic()) { assert descriptor.opens().isEmpty(); for (String source : descriptor.packages()) { addExportsToAll0(m, source); }
*** 1185,1196 **** if (opens.isQualified()) { // qualified opens Set<Module> targets = new HashSet<>(); for (String target : opens.targets()) { ! // only open to modules that are in this configuration ! Module m2 = nameToModule.get(target); if (m2 != null) { addExports0(m, source, m2); targets.add(m2); } } --- 1177,1187 ---- if (opens.isQualified()) { // qualified opens Set<Module> targets = new HashSet<>(); for (String target : opens.targets()) { ! Module m2 = findModule(target, nameToSource, nameToModule, parents); if (m2 != null) { addExports0(m, source, m2); targets.add(m2); } }
*** 1215,1226 **** if (exports.isQualified()) { // qualified exports Set<Module> targets = new HashSet<>(); for (String target : exports.targets()) { ! // only export to modules that are in this configuration ! Module m2 = nameToModule.get(target); if (m2 != null) { // skip qualified export if already open to m2 if (openToTargets == null || !openToTargets.contains(m2)) { addExports0(m, source, m2); targets.add(m2); --- 1206,1216 ---- if (exports.isQualified()) { // qualified exports Set<Module> targets = new HashSet<>(); for (String target : exports.targets()) { ! Module m2 = findModule(target, nameToSource, nameToModule, parents); if (m2 != null) { // skip qualified export if already open to m2 if (openToTargets == null || !openToTargets.contains(m2)) { addExports0(m, source, m2); targets.add(m2);
*** 1242,1251 **** --- 1232,1267 ---- m.openPackages = openPackages; if (!exportedPackages.isEmpty()) m.exportedPackages = exportedPackages; } + /** + * Find the runtime Module with the given name. The module name is the + * name of a target module in a qualified exports or opens directive. + * + * @param target The target module to find + * @param nameToSource The modules in parent layers that are read + * @param nameToModule The modules in the layer under construction + * @param parents The parent layers + */ + private static Module findModule(String target, + Map<String, Module> nameToSource, + Map<String, Module> nameToModule, + List<Layer> parents) { + Module m = nameToSource.get(target); + if (m == null) { + m = nameToModule.get(target); + if (m == null) { + for (Layer parent : parents) { + m = parent.findModule(target).orElse(null); + if (m != null) break; + } + } + } + return m; + } + // -- annotations -- /** * {@inheritDoc}
*** 1426,1441 **** public InputStream getResourceAsStream(String name) throws IOException { if (name.startsWith("/")) { name = name.substring(1); } ! if (isNamed() && !ResourceHelper.isSimpleResource(name)) { Module caller = Reflection.getCallerClass().getModule(); if (caller != this && caller != Object.class.getModule()) { // ignore packages added for proxies via addPackage Set<String> packages = getDescriptor().packages(); ! String pn = ResourceHelper.getPackageName(name); if (packages.contains(pn) && !isOpen(pn, caller)) { // resource is in package not open to caller return null; } } --- 1442,1457 ---- public InputStream getResourceAsStream(String name) throws IOException { if (name.startsWith("/")) { name = name.substring(1); } ! if (isNamed() && Resources.canEncapsulate(name)) { Module caller = Reflection.getCallerClass().getModule(); if (caller != this && caller != Object.class.getModule()) { // ignore packages added for proxies via addPackage Set<String> packages = getDescriptor().packages(); ! String pn = Resources.toPackageName(name); if (packages.contains(pn) && !isOpen(pn, caller)) { // resource is in package not open to caller return null; } }
*** 1529,1570 **** @Override public void addReadsAllUnnamed(Module m) { m.implAddReads(Module.ALL_UNNAMED_MODULE); } @Override ! public void addExports(Module m, String pn, Module other) { ! m.implAddExportsOrOpens(pn, other, false, true); } @Override ! public void addOpens(Module m, String pn, Module other) { ! m.implAddExportsOrOpens(pn, other, true, true); } @Override ! public void addExportsToAll(Module m, String pn) { ! m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true); } @Override ! public void addOpensToAll(Module m, String pn) { m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true); } @Override ! public void addExportsToAllUnnamed(Module m, String pn) { ! m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true); } @Override public void addOpensToAllUnnamed(Module m, String pn) { m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true); } @Override public void addUses(Module m, Class<?> service) { m.implAddUses(service); } @Override - public void addPackage(Module m, String pn) { - m.implAddPackage(pn, true); - } - @Override public ServicesCatalog getServicesCatalog(Layer layer) { return layer.getServicesCatalog(); } @Override public Stream<Layer> layers(Layer layer) { --- 1545,1582 ---- @Override public void addReadsAllUnnamed(Module m) { m.implAddReads(Module.ALL_UNNAMED_MODULE); } @Override ! public void addExports(Module m, String pn) { ! m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true); } @Override ! public void addExports(Module m, String pn, Module other) { ! m.implAddExportsOrOpens(pn, other, false, true); } @Override ! public void addExportsToAllUnnamed(Module m, String pn) { ! m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true); } @Override ! public void addOpens(Module m, String pn) { m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true); } @Override ! public void addOpens(Module m, String pn, Module other) { ! m.implAddExportsOrOpens(pn, other, true, true); } @Override public void addOpensToAllUnnamed(Module m, String pn) { m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true); } @Override public void addUses(Module m, Class<?> service) { m.implAddUses(service); } @Override public ServicesCatalog getServicesCatalog(Layer layer) { return layer.getServicesCatalog(); } @Override public Stream<Layer> layers(Layer layer) {
*** 1572,1583 **** } @Override public Stream<Layer> layers(ClassLoader loader) { return Layer.layers(loader); } - @Override - public boolean isStaticallyExported(Module module, String pn, Module other) { - return module.isStaticallyExportedOrOpen(pn, other, false); - } }); } } --- 1584,1591 ----
< prev index next >