jdk/src/java.base/share/classes/java/lang/reflect/Module.java
changeset 44359 c6761862ca0b
parent 43712 5dfd0950317c
equal deleted inserted replaced
44210:5a8499c4b32c 44359:c6761862ca0b
    37 import java.lang.module.ResolvedModule;
    37 import java.lang.module.ResolvedModule;
    38 import java.net.URI;
    38 import java.net.URI;
    39 import java.net.URL;
    39 import java.net.URL;
    40 import java.security.AccessController;
    40 import java.security.AccessController;
    41 import java.security.PrivilegedAction;
    41 import java.security.PrivilegedAction;
       
    42 import java.util.Collections;
    42 import java.util.HashMap;
    43 import java.util.HashMap;
    43 import java.util.HashSet;
    44 import java.util.HashSet;
       
    45 import java.util.List;
    44 import java.util.Map;
    46 import java.util.Map;
    45 import java.util.Objects;
    47 import java.util.Objects;
    46 import java.util.Optional;
    48 import java.util.Optional;
    47 import java.util.Set;
    49 import java.util.Set;
    48 import java.util.concurrent.ConcurrentHashMap;
    50 import java.util.concurrent.ConcurrentHashMap;
    49 import java.util.function.Function;
    51 import java.util.function.Function;
    50 import java.util.stream.Stream;
    52 import java.util.stream.Stream;
    51 
    53 
    52 import jdk.internal.loader.BuiltinClassLoader;
    54 import jdk.internal.loader.BuiltinClassLoader;
    53 import jdk.internal.loader.BootLoader;
    55 import jdk.internal.loader.BootLoader;
    54 import jdk.internal.loader.ResourceHelper;
       
    55 import jdk.internal.misc.JavaLangAccess;
    56 import jdk.internal.misc.JavaLangAccess;
    56 import jdk.internal.misc.JavaLangReflectModuleAccess;
    57 import jdk.internal.misc.JavaLangReflectModuleAccess;
    57 import jdk.internal.misc.SharedSecrets;
    58 import jdk.internal.misc.SharedSecrets;
    58 import jdk.internal.module.ServicesCatalog;
    59 import jdk.internal.module.ServicesCatalog;
       
    60 import jdk.internal.module.Resources;
    59 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
    61 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
    60 import jdk.internal.org.objectweb.asm.Attribute;
    62 import jdk.internal.org.objectweb.asm.Attribute;
    61 import jdk.internal.org.objectweb.asm.ClassReader;
    63 import jdk.internal.org.objectweb.asm.ClassReader;
    62 import jdk.internal.org.objectweb.asm.ClassVisitor;
    64 import jdk.internal.org.objectweb.asm.ClassVisitor;
    63 import jdk.internal.org.objectweb.asm.ClassWriter;
    65 import jdk.internal.org.objectweb.asm.ClassWriter;
   367      * Makes the given {@code Module} readable to this module.
   369      * Makes the given {@code Module} readable to this module.
   368      *
   370      *
   369      * If {@code syncVM} is {@code true} then the VM is notified.
   371      * If {@code syncVM} is {@code true} then the VM is notified.
   370      */
   372      */
   371     private void implAddReads(Module other, boolean syncVM) {
   373     private void implAddReads(Module other, boolean syncVM) {
   372         Objects.requireNonNull(other);
   374         if (!canRead(other)) {
   373 
   375             // update VM first, just in case it fails
   374         // nothing to do
   376             if (syncVM) {
   375         if (other == this || !this.isNamed())
   377                 if (other == ALL_UNNAMED_MODULE) {
   376             return;
   378                     addReads0(this, null);
   377 
   379                 } else {
   378         // check if we already read this module
   380                     addReads0(this, other);
   379         Set<Module> reads = this.reads;
   381                 }
   380         if (reads != null && reads.contains(other))
   382             }
   381             return;
   383 
   382 
   384             // add reflective read
   383         // update VM first, just in case it fails
   385             reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
   384         if (syncVM) {
   386         }
   385             if (other == ALL_UNNAMED_MODULE) {
       
   386                 addReads0(this, null);
       
   387             } else {
       
   388                 addReads0(this, other);
       
   389             }
       
   390         }
       
   391 
       
   392         // add reflective read
       
   393         reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
       
   394     }
   387     }
   395 
   388 
   396 
   389 
   397     // -- exported and open packages --
   390     // -- exported and open packages --
   398 
   391 
   551 
   544 
   552     /**
   545     /**
   553      * Returns {@code true} if this module exports or opens a package to
   546      * Returns {@code true} if this module exports or opens a package to
   554      * the given module via its module declaration.
   547      * the given module via its module declaration.
   555      */
   548      */
   556     boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
   549     private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
   557         // package is open to everyone or <other>
   550         // package is open to everyone or <other>
   558         Map<String, Set<Module>> openPackages = this.openPackages;
   551         Map<String, Set<Module>> openPackages = this.openPackages;
   559         if (openPackages != null) {
   552         if (openPackages != null) {
   560             Set<Module> targets = openPackages.get(pn);
   553             Set<Module> targets = openPackages.get(pn);
   561             if (targets != null) {
   554             if (targets != null) {
   907 
   900 
   908     /**
   901     /**
   909      * Returns an array of the package names of the packages in this module.
   902      * Returns an array of the package names of the packages in this module.
   910      *
   903      *
   911      * <p> For named modules, the returned array contains an element for each
   904      * <p> For named modules, the returned array contains an element for each
   912      * package in the module. It may contain elements corresponding to packages
   905      * package in the module. </p>
   913      * added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a>
       
   914      * for example, after it was loaded.
       
   915      *
   906      *
   916      * <p> For unnamed modules, this method is the equivalent to invoking the
   907      * <p> For unnamed modules, this method is the equivalent to invoking the
   917      * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
   908      * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
   918      * this module's class loader and returning the array of package names. </p>
   909      * this module's class loader and returning the array of package names. </p>
   919      *
   910      *
   945             } else {
   936             } else {
   946                 packages = SharedSecrets.getJavaLangAccess().packages(loader);
   937                 packages = SharedSecrets.getJavaLangAccess().packages(loader);
   947             }
   938             }
   948             return packages.map(Package::getName).toArray(String[]::new);
   939             return packages.map(Package::getName).toArray(String[]::new);
   949         }
   940         }
   950     }
       
   951 
       
   952     /**
       
   953      * Add a package to this module.
       
   954      *
       
   955      * @apiNote This method is for Proxy use.
       
   956      */
       
   957     void addPackage(String pn) {
       
   958         implAddPackage(pn, true);
       
   959     }
   941     }
   960 
   942 
   961     /**
   943     /**
   962      * Add a package to this module without notifying the VM.
   944      * Add a package to this module without notifying the VM.
   963      *
   945      *
  1078             Module m = nameToModule.get(mn);
  1060             Module m = nameToModule.get(mn);
  1079             assert m != null;
  1061             assert m != null;
  1080 
  1062 
  1081             // reads
  1063             // reads
  1082             Set<Module> reads = new HashSet<>();
  1064             Set<Module> reads = new HashSet<>();
       
  1065 
       
  1066             // name -> source Module when in parent layer
       
  1067             Map<String, Module> nameToSource = Collections.emptyMap();
       
  1068 
  1083             for (ResolvedModule other : resolvedModule.reads()) {
  1069             for (ResolvedModule other : resolvedModule.reads()) {
  1084                 Module m2 = null;
  1070                 Module m2 = null;
  1085                 if (other.configuration() == cf) {
  1071                 if (other.configuration() == cf) {
  1086                     String dn = other.reference().descriptor().name();
  1072                     // this configuration
  1087                     m2 = nameToModule.get(dn);
  1073                     m2 = nameToModule.get(other.name());
       
  1074                     assert m2 != null;
  1088                 } else {
  1075                 } else {
       
  1076                     // parent layer
  1089                     for (Layer parent: layer.parents()) {
  1077                     for (Layer parent: layer.parents()) {
  1090                         m2 = findModule(parent, other);
  1078                         m2 = findModule(parent, other);
  1091                         if (m2 != null)
  1079                         if (m2 != null)
  1092                             break;
  1080                             break;
  1093                     }
  1081                     }
  1094                 }
  1082                     assert m2 != null;
  1095                 assert m2 != null;
  1083                     if (nameToSource.isEmpty())
  1096 
  1084                         nameToSource = new HashMap<>();
       
  1085                     nameToSource.put(other.name(), m2);
       
  1086                 }
  1097                 reads.add(m2);
  1087                 reads.add(m2);
  1098 
  1088 
  1099                 // update VM view
  1089                 // update VM view
  1100                 addReads0(m, m2);
  1090                 addReads0(m, m2);
  1101             }
  1091             }
  1105             if (descriptor.isAutomatic()) {
  1095             if (descriptor.isAutomatic()) {
  1106                 m.implAddReads(ALL_UNNAMED_MODULE, true);
  1096                 m.implAddReads(ALL_UNNAMED_MODULE, true);
  1107             }
  1097             }
  1108 
  1098 
  1109             // exports and opens
  1099             // exports and opens
  1110             initExportsAndOpens(descriptor, nameToModule, m);
  1100             initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
  1111         }
  1101         }
  1112 
  1102 
  1113         // register the modules in the boot layer
  1103         // register the modules in the boot layer
  1114         if (isBootLayer) {
  1104         if (isBootLayer) {
  1115             for (ResolvedModule resolvedModule : cf.modules()) {
  1105             for (ResolvedModule resolvedModule : cf.modules()) {
  1157                     return m;
  1147                     return m;
  1158                 })
  1148                 })
  1159                 .orElse(null);
  1149                 .orElse(null);
  1160     }
  1150     }
  1161 
  1151 
       
  1152 
  1162     /**
  1153     /**
  1163      * Initialize the maps of exported and open packages for module m.
  1154      * Initialize the maps of exported and open packages for module m.
  1164      */
  1155      */
  1165     private static void initExportsAndOpens(ModuleDescriptor descriptor,
  1156     private static void initExportsAndOpens(Module m,
       
  1157                                             Map<String, Module> nameToSource,
  1166                                             Map<String, Module> nameToModule,
  1158                                             Map<String, Module> nameToModule,
  1167                                             Module m)
  1159                                             List<Layer> parents) {
  1168     {
       
  1169         // The VM doesn't special case open or automatic modules so need to
  1160         // The VM doesn't special case open or automatic modules so need to
  1170         // export all packages
  1161         // export all packages
       
  1162         ModuleDescriptor descriptor = m.getDescriptor();
  1171         if (descriptor.isOpen() || descriptor.isAutomatic()) {
  1163         if (descriptor.isOpen() || descriptor.isAutomatic()) {
  1172             assert descriptor.opens().isEmpty();
  1164             assert descriptor.opens().isEmpty();
  1173             for (String source : descriptor.packages()) {
  1165             for (String source : descriptor.packages()) {
  1174                 addExportsToAll0(m, source);
  1166                 addExportsToAll0(m, source);
  1175             }
  1167             }
  1185 
  1177 
  1186             if (opens.isQualified()) {
  1178             if (opens.isQualified()) {
  1187                 // qualified opens
  1179                 // qualified opens
  1188                 Set<Module> targets = new HashSet<>();
  1180                 Set<Module> targets = new HashSet<>();
  1189                 for (String target : opens.targets()) {
  1181                 for (String target : opens.targets()) {
  1190                     // only open to modules that are in this configuration
  1182                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
  1191                     Module m2 = nameToModule.get(target);
       
  1192                     if (m2 != null) {
  1183                     if (m2 != null) {
  1193                         addExports0(m, source, m2);
  1184                         addExports0(m, source, m2);
  1194                         targets.add(m2);
  1185                         targets.add(m2);
  1195                     }
  1186                     }
  1196                 }
  1187                 }
  1215 
  1206 
  1216             if (exports.isQualified()) {
  1207             if (exports.isQualified()) {
  1217                 // qualified exports
  1208                 // qualified exports
  1218                 Set<Module> targets = new HashSet<>();
  1209                 Set<Module> targets = new HashSet<>();
  1219                 for (String target : exports.targets()) {
  1210                 for (String target : exports.targets()) {
  1220                     // only export to modules that are in this configuration
  1211                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
  1221                     Module m2 = nameToModule.get(target);
       
  1222                     if (m2 != null) {
  1212                     if (m2 != null) {
  1223                         // skip qualified export if already open to m2
  1213                         // skip qualified export if already open to m2
  1224                         if (openToTargets == null || !openToTargets.contains(m2)) {
  1214                         if (openToTargets == null || !openToTargets.contains(m2)) {
  1225                             addExports0(m, source, m2);
  1215                             addExports0(m, source, m2);
  1226                             targets.add(m2);
  1216                             targets.add(m2);
  1240 
  1230 
  1241         if (!openPackages.isEmpty())
  1231         if (!openPackages.isEmpty())
  1242             m.openPackages = openPackages;
  1232             m.openPackages = openPackages;
  1243         if (!exportedPackages.isEmpty())
  1233         if (!exportedPackages.isEmpty())
  1244             m.exportedPackages = exportedPackages;
  1234             m.exportedPackages = exportedPackages;
       
  1235     }
       
  1236 
       
  1237     /**
       
  1238      * Find the runtime Module with the given name. The module name is the
       
  1239      * name of a target module in a qualified exports or opens directive.
       
  1240      *
       
  1241      * @param target The target module to find
       
  1242      * @param nameToSource The modules in parent layers that are read
       
  1243      * @param nameToModule The modules in the layer under construction
       
  1244      * @param parents The parent layers
       
  1245      */
       
  1246     private static Module findModule(String target,
       
  1247                                      Map<String, Module> nameToSource,
       
  1248                                      Map<String, Module> nameToModule,
       
  1249                                      List<Layer> parents) {
       
  1250         Module m = nameToSource.get(target);
       
  1251         if (m == null) {
       
  1252             m = nameToModule.get(target);
       
  1253             if (m == null) {
       
  1254                 for (Layer parent : parents) {
       
  1255                     m = parent.findModule(target).orElse(null);
       
  1256                     if (m != null) break;
       
  1257                 }
       
  1258             }
       
  1259         }
       
  1260         return m;
  1245     }
  1261     }
  1246 
  1262 
  1247 
  1263 
  1248     // -- annotations --
  1264     // -- annotations --
  1249 
  1265 
  1426     public InputStream getResourceAsStream(String name) throws IOException {
  1442     public InputStream getResourceAsStream(String name) throws IOException {
  1427         if (name.startsWith("/")) {
  1443         if (name.startsWith("/")) {
  1428             name = name.substring(1);
  1444             name = name.substring(1);
  1429         }
  1445         }
  1430 
  1446 
  1431         if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
  1447         if (isNamed() && Resources.canEncapsulate(name)) {
  1432             Module caller = Reflection.getCallerClass().getModule();
  1448             Module caller = Reflection.getCallerClass().getModule();
  1433             if (caller != this && caller != Object.class.getModule()) {
  1449             if (caller != this && caller != Object.class.getModule()) {
  1434                 // ignore packages added for proxies via addPackage
  1450                 // ignore packages added for proxies via addPackage
  1435                 Set<String> packages = getDescriptor().packages();
  1451                 Set<String> packages = getDescriptor().packages();
  1436                 String pn = ResourceHelper.getPackageName(name);
  1452                 String pn = Resources.toPackageName(name);
  1437                 if (packages.contains(pn) && !isOpen(pn, caller)) {
  1453                 if (packages.contains(pn) && !isOpen(pn, caller)) {
  1438                     // resource is in package not open to caller
  1454                     // resource is in package not open to caller
  1439                     return null;
  1455                     return null;
  1440                 }
  1456                 }
  1441             }
  1457             }
  1529                 @Override
  1545                 @Override
  1530                 public void addReadsAllUnnamed(Module m) {
  1546                 public void addReadsAllUnnamed(Module m) {
  1531                     m.implAddReads(Module.ALL_UNNAMED_MODULE);
  1547                     m.implAddReads(Module.ALL_UNNAMED_MODULE);
  1532                 }
  1548                 }
  1533                 @Override
  1549                 @Override
       
  1550                 public void addExports(Module m, String pn) {
       
  1551                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
       
  1552                 }
       
  1553                 @Override
  1534                 public void addExports(Module m, String pn, Module other) {
  1554                 public void addExports(Module m, String pn, Module other) {
  1535                     m.implAddExportsOrOpens(pn, other, false, true);
  1555                     m.implAddExportsOrOpens(pn, other, false, true);
       
  1556                 }
       
  1557                 @Override
       
  1558                 public void addExportsToAllUnnamed(Module m, String pn) {
       
  1559                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
       
  1560                 }
       
  1561                 @Override
       
  1562                 public void addOpens(Module m, String pn) {
       
  1563                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
  1536                 }
  1564                 }
  1537                 @Override
  1565                 @Override
  1538                 public void addOpens(Module m, String pn, Module other) {
  1566                 public void addOpens(Module m, String pn, Module other) {
  1539                     m.implAddExportsOrOpens(pn, other, true, true);
  1567                     m.implAddExportsOrOpens(pn, other, true, true);
  1540                 }
  1568                 }
  1541                 @Override
  1569                 @Override
  1542                 public void addExportsToAll(Module m, String pn) {
       
  1543                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
       
  1544                 }
       
  1545                 @Override
       
  1546                 public void addOpensToAll(Module m, String pn) {
       
  1547                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
       
  1548                 }
       
  1549                 @Override
       
  1550                 public void addExportsToAllUnnamed(Module m, String pn) {
       
  1551                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
       
  1552                 }
       
  1553                 @Override
       
  1554                 public void addOpensToAllUnnamed(Module m, String pn) {
  1570                 public void addOpensToAllUnnamed(Module m, String pn) {
  1555                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
  1571                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
  1556                 }
  1572                 }
  1557                 @Override
  1573                 @Override
  1558                 public void addUses(Module m, Class<?> service) {
  1574                 public void addUses(Module m, Class<?> service) {
  1559                     m.implAddUses(service);
  1575                     m.implAddUses(service);
  1560                 }
  1576                 }
  1561                 @Override
  1577                 @Override
  1562                 public void addPackage(Module m, String pn) {
       
  1563                     m.implAddPackage(pn, true);
       
  1564                 }
       
  1565                 @Override
       
  1566                 public ServicesCatalog getServicesCatalog(Layer layer) {
  1578                 public ServicesCatalog getServicesCatalog(Layer layer) {
  1567                     return layer.getServicesCatalog();
  1579                     return layer.getServicesCatalog();
  1568                 }
  1580                 }
  1569                 @Override
  1581                 @Override
  1570                 public Stream<Layer> layers(Layer layer) {
  1582                 public Stream<Layer> layers(Layer layer) {
  1572                 }
  1584                 }
  1573                 @Override
  1585                 @Override
  1574                 public Stream<Layer> layers(ClassLoader loader) {
  1586                 public Stream<Layer> layers(ClassLoader loader) {
  1575                     return Layer.layers(loader);
  1587                     return Layer.layers(loader);
  1576                 }
  1588                 }
  1577                 @Override
       
  1578                 public boolean isStaticallyExported(Module module, String pn, Module other) {
       
  1579                     return module.isStaticallyExportedOrOpen(pn, other, false);
       
  1580                 }
       
  1581             });
  1589             });
  1582     }
  1590     }
  1583 }
  1591 }