1 /*
   2  * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 
  28 import java.io.IOException;
  29 import java.io.InputStream;
  30 import java.lang.annotation.Annotation;
  31 import java.lang.module.Configuration;
  32 import java.lang.module.ModuleReference;
  33 import java.lang.module.ModuleDescriptor;
  34 import java.lang.module.ModuleDescriptor.Exports;
  35 import java.lang.module.ModuleDescriptor.Opens;
  36 import java.lang.module.ModuleDescriptor.Version;
  37 import java.lang.module.ResolvedModule;
  38 import java.lang.reflect.AccessFlag;
  39 import java.lang.reflect.AnnotatedElement;
  40 import java.net.URI;
  41 import java.net.URL;
  42 import java.security.AccessController;
  43 import java.security.PrivilegedAction;
  44 import java.util.HashMap;
  45 import java.util.HashSet;
  46 import java.util.List;
  47 import java.util.Map;
  48 import java.util.Objects;
  49 import java.util.Optional;
  50 import java.util.Set;
  51 import java.util.concurrent.ConcurrentHashMap;
  52 import java.util.function.Function;
  53 import java.util.stream.Collectors;
  54 import java.util.stream.Stream;
  55 import jdk.internal.classfile.AccessFlags;
  56 import jdk.internal.classfile.Attribute;
  57 import jdk.internal.classfile.ClassModel;
  58 import jdk.internal.classfile.ClassTransform;
  59 import jdk.internal.classfile.Classfile;
  60 import jdk.internal.classfile.attribute.ModuleAttribute;
  61 import jdk.internal.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
  62 
  63 import jdk.internal.javac.PreviewFeature;
  64 import jdk.internal.loader.BuiltinClassLoader;
  65 import jdk.internal.loader.BootLoader;
  66 import jdk.internal.loader.ClassLoaders;
  67 import jdk.internal.misc.CDS;
  68 import jdk.internal.misc.Unsafe;
  69 import jdk.internal.module.ModuleBootstrap;
  70 import jdk.internal.module.ModuleLoaderMap;
  71 import jdk.internal.module.ServicesCatalog;
  72 import jdk.internal.module.Resources;
  73 import jdk.internal.reflect.CallerSensitive;
  74 import jdk.internal.reflect.Reflection;
  75 import jdk.internal.vm.annotation.Stable;
  76 import sun.security.util.SecurityConstants;
  77 
  78 /**
  79  * Represents a run-time module, either {@link #isNamed() named} or unnamed.
  80  *
  81  * <p> Named modules have a {@link #getName() name} and are constructed by the
  82  * Java Virtual Machine when a graph of modules is defined to the Java virtual
  83  * machine to create a {@linkplain ModuleLayer module layer}. </p>
  84  *
  85  * <p> An unnamed module does not have a name. There is an unnamed module for
  86  * each {@link ClassLoader ClassLoader}, obtained by invoking its {@link
  87  * ClassLoader#getUnnamedModule() getUnnamedModule} method. All types that are
  88  * not in a named module are members of their defining class loader's unnamed
  89  * module. </p>
  90  *
  91  * <p> The package names that are parameters or returned by methods defined in
  92  * this class are the fully-qualified names of the packages as defined in
  93  * section {@jls 6.5.3} of <cite>The Java Language Specification</cite>, for
  94  * example, {@code "java.lang"}. </p>
  95  *
  96  * <p> Unless otherwise specified, passing a {@code null} argument to a method
  97  * in this class causes a {@link NullPointerException NullPointerException} to
  98  * be thrown. </p>
  99  *
 100  * @since 9
 101  * @see Class#getModule()
 102  * @jls 7.7 Module Declarations
 103  */
 104 
 105 public final class Module implements AnnotatedElement {
 106 
 107     // the layer that contains this module, can be null
 108     private final ModuleLayer layer;
 109 
 110     // module name and loader, these fields are read by VM
 111     private final String name;
 112     private final ClassLoader loader;
 113 
 114     // the module descriptor
 115     private final ModuleDescriptor descriptor;
 116 
 117     // true, if this module allows restricted native access
 118     // Accessing this variable is made through Unsafe in order to use the
 119     // memory semantics that preserves ordering and visibility across threads.
 120     @Stable
 121     private boolean enableNativeAccess;
 122 
 123     /**
 124      * Creates a new named Module. The resulting Module will be defined to the
 125      * VM but will not read any other modules, will not have any exports setup
 126      * and will not be registered in the service catalog.
 127      */
 128     Module(ModuleLayer layer,
 129            ClassLoader loader,
 130            ModuleDescriptor descriptor,
 131            URI uri)
 132     {
 133         this.layer = layer;
 134         this.name = descriptor.name();
 135         this.loader = loader;
 136         this.descriptor = descriptor;
 137 
 138         // define module to VM
 139 
 140         boolean isOpen = descriptor.isOpen() || descriptor.isAutomatic();
 141         Version version = descriptor.version().orElse(null);
 142         String vs = Objects.toString(version, null);
 143         String loc = Objects.toString(uri, null);
 144         Object[] packages = descriptor.packages().toArray();
 145         defineModule0(this, isOpen, vs, loc, packages);
 146         if (loader == null || loader == ClassLoaders.platformClassLoader()) {
 147             // boot/builtin modules are always native
 148             implAddEnableNativeAccess();
 149         }
 150     }
 151 
 152 
 153     /**
 154      * Create the unnamed Module for the given ClassLoader.
 155      *
 156      * @see ClassLoader#getUnnamedModule
 157      */
 158     Module(ClassLoader loader) {
 159         this.layer = null;
 160         this.name = null;
 161         this.loader = loader;
 162         this.descriptor = null;
 163     }
 164 
 165 
 166     /**
 167      * Creates a named module but without defining the module to the VM.
 168      *
 169      * @apiNote This constructor is for VM white-box testing.
 170      */
 171     Module(ClassLoader loader, ModuleDescriptor descriptor) {
 172         this.layer = null;
 173         this.name = descriptor.name();
 174         this.loader = loader;
 175         this.descriptor = descriptor;
 176     }
 177 
 178 
 179     /**
 180      * Returns {@code true} if this module is a named module.
 181      *
 182      * @return {@code true} if this is a named module
 183      *
 184      * @see ClassLoader#getUnnamedModule()
 185      * @jls 7.7.5 Unnamed Modules
 186      */
 187     public boolean isNamed() {
 188         return name != null;
 189     }
 190 
 191     /**
 192      * Returns the module name or {@code null} if this module is an unnamed
 193      * module.
 194      *
 195      * @return The module name
 196      */
 197     public String getName() {
 198         return name;
 199     }
 200 
 201     /**
 202      * Returns the {@code ClassLoader} for this module.
 203      *
 204      * <p> If there is a security manager then its {@code checkPermission}
 205      * method if first called with a {@code RuntimePermission("getClassLoader")}
 206      * permission to check that the caller is allowed to get access to the
 207      * class loader. </p>
 208      *
 209      * @return The class loader for this module
 210      *
 211      * @throws SecurityException
 212      *         If denied by the security manager
 213      */
 214     public ClassLoader getClassLoader() {
 215         @SuppressWarnings("removal")
 216         SecurityManager sm = System.getSecurityManager();
 217         if (sm != null) {
 218             sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 219         }
 220         return loader;
 221     }
 222 
 223     /**
 224      * Returns the module descriptor for this module or {@code null} if this
 225      * module is an unnamed module.
 226      *
 227      * @return The module descriptor for this module
 228      */
 229     public ModuleDescriptor getDescriptor() {
 230         return descriptor;
 231     }
 232 
 233     /**
 234      * Returns the module layer that contains this module or {@code null} if
 235      * this module is not in a module layer.
 236      *
 237      * A module layer contains named modules and therefore this method always
 238      * returns {@code null} when invoked on an unnamed module.
 239      *
 240      * <p> <a href="reflect/Proxy.html#dynamicmodule">Dynamic modules</a> are
 241      * named modules that are generated at runtime. A dynamic module may or may
 242      * not be in a module layer. </p>
 243      *
 244      * @return The module layer that contains this module
 245      *
 246      * @see java.lang.reflect.Proxy
 247      */
 248     public ModuleLayer getLayer() {
 249         if (isNamed()) {
 250             ModuleLayer layer = this.layer;
 251             if (layer != null)
 252                 return layer;
 253 
 254             // special-case java.base as it is created before the boot layer
 255             if (loader == null && name.equals("java.base")) {
 256                 return ModuleLayer.boot();
 257             }
 258         }
 259         return null;
 260     }
 261 
 262     /**
 263      * Update this module to allow access to restricted methods.
 264      */
 265     Module implAddEnableNativeAccess() {
 266         EnableNativeAccess.trySetEnableNativeAccess(this);
 267         return this;
 268     }
 269 
 270     /**
 271      * Returns {@code true} if this module can access
 272      * <a href="foreign/package-summary.html#restricted"><em>restricted</em></a> methods.
 273      *
 274      * @return {@code true} if this module can access <em>restricted</em> methods.
 275      * @since 20
 276      */
 277     @PreviewFeature(feature = PreviewFeature.Feature.FOREIGN)
 278     public boolean isNativeAccessEnabled() {
 279         Module target = moduleForNativeAccess();
 280         return EnableNativeAccess.isNativeAccessEnabled(target);
 281     }
 282 
 283     /**
 284      * This class is used to be able to bootstrap without using Unsafe
 285      * in the outer Module class as that would create a circular initializer dependency.
 286      */
 287     private static final class EnableNativeAccess {
 288 
 289         private EnableNativeAccess() {}
 290 
 291         private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 292         private static final long FIELD_OFFSET = UNSAFE.objectFieldOffset(Module.class, "enableNativeAccess");
 293 
 294         private static boolean isNativeAccessEnabled(Module target) {
 295             return UNSAFE.getBooleanVolatile(target, FIELD_OFFSET);
 296         }
 297 
 298         // Atomically sets enableNativeAccess if not already set
 299         // returning if the value was updated
 300         private static boolean trySetEnableNativeAccess(Module target) {
 301             return UNSAFE.compareAndSetBoolean(target, FIELD_OFFSET, false, true);
 302         }
 303     }
 304 
 305     // Returns the Module object that holds the enableNativeAccess
 306     // flag for this module.
 307     private Module moduleForNativeAccess() {
 308         return isNamed() ? this : ALL_UNNAMED_MODULE;
 309     }
 310 
 311     // This is invoked from Reflection.ensureNativeAccess
 312     void ensureNativeAccess(Class<?> owner, String methodName) {
 313         // The target module whose enableNativeAccess flag is ensured
 314         Module target = moduleForNativeAccess();
 315         if (!EnableNativeAccess.isNativeAccessEnabled(target)) {
 316             if (ModuleBootstrap.hasEnableNativeAccessFlag()) {
 317                 throw new IllegalCallerException("Illegal native access from: " + this);
 318             }
 319             if (EnableNativeAccess.trySetEnableNativeAccess(target)) {
 320                 // warn and set flag, so that only one warning is reported per module
 321                 String cls = owner.getName();
 322                 String mtd = cls + "::" + methodName;
 323                 String mod = isNamed() ? "module " + getName() : "the unnamed module";
 324                 String modflag = isNamed() ? getName() : "ALL-UNNAMED";
 325                 System.err.printf("""
 326                         WARNING: A restricted method in %s has been called
 327                         WARNING: %s has been called by %s
 328                         WARNING: Use --enable-native-access=%s to avoid a warning for this module
 329                         %n""", cls, mtd, mod, modflag);
 330             }
 331         }
 332     }
 333 
 334     /**
 335      * Update all unnamed modules to allow access to restricted methods.
 336      */
 337     static void implAddEnableNativeAccessToAllUnnamed() {
 338         EnableNativeAccess.trySetEnableNativeAccess(ALL_UNNAMED_MODULE);
 339     }
 340 
 341     // --
 342 
 343     // special Module to mean "all unnamed modules"
 344     private static final Module ALL_UNNAMED_MODULE;
 345     private static final Set<Module> ALL_UNNAMED_MODULE_SET;
 346 
 347     // special Module to mean "everyone"
 348     private static final Module EVERYONE_MODULE;
 349     private static final Set<Module> EVERYONE_SET;
 350 
 351     private static class ArchivedData {
 352         private static ArchivedData archivedData;
 353         private final Module allUnnamedModule;
 354         private final Set<Module> allUnnamedModules;
 355         private final Module everyoneModule;
 356         private final Set<Module> everyoneSet;
 357 
 358         private ArchivedData() {
 359             this.allUnnamedModule = ALL_UNNAMED_MODULE;
 360             this.allUnnamedModules = ALL_UNNAMED_MODULE_SET;
 361             this.everyoneModule = EVERYONE_MODULE;
 362             this.everyoneSet = EVERYONE_SET;
 363         }
 364 
 365         static void archive() {
 366             archivedData = new ArchivedData();
 367         }
 368 
 369         static ArchivedData get() {
 370             return archivedData;
 371         }
 372 
 373         static {
 374             CDS.initializeFromArchive(ArchivedData.class);
 375         }
 376     }
 377 
 378     static {
 379         ArchivedData archivedData = ArchivedData.get();
 380         if (archivedData != null) {
 381             ALL_UNNAMED_MODULE = archivedData.allUnnamedModule;
 382             ALL_UNNAMED_MODULE_SET = archivedData.allUnnamedModules;
 383             EVERYONE_MODULE = archivedData.everyoneModule;
 384             EVERYONE_SET = archivedData.everyoneSet;
 385         } else {
 386             ALL_UNNAMED_MODULE = new Module(null);
 387             ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
 388             EVERYONE_MODULE = new Module(null);
 389             EVERYONE_SET = Set.of(EVERYONE_MODULE);
 390             ArchivedData.archive();
 391         }
 392     }
 393 
 394     /**
 395      * The holder of data structures to support readability, exports, and
 396      * service use added at runtime with the reflective APIs.
 397      */
 398     private static class ReflectionData {
 399         /**
 400          * A module (1st key) reads another module (2nd key)
 401          */
 402         static final WeakPairMap<Module, Module, Boolean> reads =
 403             new WeakPairMap<>();
 404 
 405         /**
 406          * A module (1st key) exports or opens a package to another module
 407          * (2nd key). The map value is a map of package name to a boolean
 408          * that indicates if the package is opened.
 409          */
 410         static final WeakPairMap<Module, Module, Map<String, Boolean>> exports =
 411             new WeakPairMap<>();
 412 
 413         /**
 414          * A module (1st key) uses a service (2nd key)
 415          */
 416         static final WeakPairMap<Module, Class<?>, Boolean> uses =
 417             new WeakPairMap<>();
 418     }
 419 
 420 
 421     // -- readability --
 422 
 423     // the modules that this module reads
 424     private volatile Set<Module> reads;
 425 
 426     /**
 427      * Indicates if this module reads the given module. This method returns
 428      * {@code true} if invoked to test if this module reads itself. It also
 429      * returns {@code true} if invoked on an unnamed module (as unnamed
 430      * modules read all modules).
 431      *
 432      * @param  other
 433      *         The other module
 434      *
 435      * @return {@code true} if this module reads {@code other}
 436      *
 437      * @see #addReads(Module)
 438      */
 439     public boolean canRead(Module other) {
 440         Objects.requireNonNull(other);
 441 
 442         // an unnamed module reads all modules
 443         if (!this.isNamed())
 444             return true;
 445 
 446         // all modules read themselves
 447         if (other == this)
 448             return true;
 449 
 450         // check if this module reads other
 451         if (other.isNamed()) {
 452             Set<Module> reads = this.reads; // volatile read
 453             if (reads != null && reads.contains(other))
 454                 return true;
 455         }
 456 
 457         // check if this module reads the other module reflectively
 458         if (ReflectionData.reads.containsKeyPair(this, other))
 459             return true;
 460 
 461         // if other is an unnamed module then check if this module reads
 462         // all unnamed modules
 463         if (!other.isNamed()
 464             && ReflectionData.reads.containsKeyPair(this, ALL_UNNAMED_MODULE))
 465             return true;
 466 
 467         return false;
 468     }
 469 
 470     /**
 471      * If the caller's module is this module then update this module to read
 472      * the given module.
 473      *
 474      * This method is a no-op if {@code other} is this module (all modules read
 475      * themselves), this module is an unnamed module (as unnamed modules read
 476      * all modules), or this module already reads {@code other}.
 477      *
 478      * @implNote <em>Read edges</em> added by this method are <em>weak</em> and
 479      * do not prevent {@code other} from being GC'ed when this module is
 480      * strongly reachable.
 481      *
 482      * @param  other
 483      *         The other module
 484      *
 485      * @return this module
 486      *
 487      * @throws IllegalCallerException
 488      *         If this is a named module and the caller's module is not this
 489      *         module
 490      *
 491      * @see #canRead
 492      */
 493     @CallerSensitive
 494     public Module addReads(Module other) {
 495         Objects.requireNonNull(other);
 496         if (this.isNamed()) {
 497             Module caller = getCallerModule(Reflection.getCallerClass());
 498             if (caller != this) {
 499                 throw new IllegalCallerException(caller + " != " + this);
 500             }
 501             implAddReads(other, true);
 502         }
 503         return this;
 504     }
 505 
 506     /**
 507      * Updates this module to read another module.
 508      *
 509      * @apiNote Used by the --add-reads command line option.
 510      */
 511     void implAddReads(Module other) {
 512         implAddReads(other, true);
 513     }
 514 
 515     /**
 516      * Updates this module to read all unnamed modules.
 517      *
 518      * @apiNote Used by the --add-reads command line option.
 519      */
 520     void implAddReadsAllUnnamed() {
 521         implAddReads(Module.ALL_UNNAMED_MODULE, true);
 522     }
 523 
 524     /**
 525      * Updates this module to read another module without notifying the VM.
 526      *
 527      * @apiNote This method is for VM white-box testing.
 528      */
 529     void implAddReadsNoSync(Module other) {
 530         implAddReads(other, false);
 531     }
 532 
 533     /**
 534      * Makes the given {@code Module} readable to this module.
 535      *
 536      * If {@code syncVM} is {@code true} then the VM is notified.
 537      */
 538     private void implAddReads(Module other, boolean syncVM) {
 539         Objects.requireNonNull(other);
 540         if (!canRead(other)) {
 541             // update VM first, just in case it fails
 542             if (syncVM) {
 543                 if (other == ALL_UNNAMED_MODULE) {
 544                     addReads0(this, null);
 545                 } else {
 546                     addReads0(this, other);
 547                 }
 548             }
 549 
 550             // add reflective read
 551             ReflectionData.reads.putIfAbsent(this, other, Boolean.TRUE);
 552         }
 553     }
 554 
 555 
 556     // -- exported and open packages --
 557 
 558     // the packages are open to other modules, can be null
 559     // if the value contains EVERYONE_MODULE then the package is open to all
 560     private volatile Map<String, Set<Module>> openPackages;
 561 
 562     // the packages that are exported, can be null
 563     // if the value contains EVERYONE_MODULE then the package is exported to all
 564     private volatile Map<String, Set<Module>> exportedPackages;
 565 
 566     /**
 567      * Returns {@code true} if this module exports the given package to at
 568      * least the given module.
 569      *
 570      * <p> This method returns {@code true} if invoked to test if a package in
 571      * this module is exported to itself. It always returns {@code true} when
 572      * invoked on an unnamed module. A package that is {@link #isOpen open} to
 573      * the given module is considered exported to that module at run-time and
 574      * so this method returns {@code true} if the package is open to the given
 575      * module. </p>
 576      *
 577      * <p> This method does not check if the given module reads this module. </p>
 578      *
 579      * @param  pn
 580      *         The package name
 581      * @param  other
 582      *         The other module
 583      *
 584      * @return {@code true} if this module exports the package to at least the
 585      *         given module
 586      *
 587      * @see ModuleDescriptor#exports()
 588      * @see #addExports(String,Module)
 589      */
 590     public boolean isExported(String pn, Module other) {
 591         Objects.requireNonNull(pn);
 592         Objects.requireNonNull(other);
 593         return implIsExportedOrOpen(pn, other, /*open*/false);
 594     }
 595 
 596     /**
 597      * Returns {@code true} if this module has <em>opened</em> a package to at
 598      * least the given module.
 599      *
 600      * <p> This method returns {@code true} if invoked to test if a package in
 601      * this module is open to itself. It returns {@code true} when invoked on an
 602      * {@link ModuleDescriptor#isOpen open} module with a package in the module.
 603      * It always returns {@code true} when invoked on an unnamed module. </p>
 604      *
 605      * <p> This method does not check if the given module reads this module. </p>
 606      *
 607      * @apiNote A package {@code p} opened to module {@code M} allows code in
 608      * {@code M} do {@linkplain java.lang.reflect.AccessibleObject#setAccessible(boolean)
 609      * deep reflection} on all types in the package.
 610      * Further, if {@code M} reads this module, it can obtain a
 611      * {@link java.lang.invoke.MethodHandles.Lookup Lookup} object that is allowed to
 612      * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) define classes}
 613      * in package {@code p}.
 614      *
 615      * @param  pn
 616      *         The package name
 617      * @param  other
 618      *         The other module
 619      *
 620      * @return {@code true} if this module has <em>opened</em> the package
 621      *         to at least the given module
 622      *
 623      * @see ModuleDescriptor#opens()
 624      * @see #addOpens(String,Module)
 625      * @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
 626      * @see java.lang.invoke.MethodHandles#privateLookupIn
 627      */
 628     public boolean isOpen(String pn, Module other) {
 629         Objects.requireNonNull(pn);
 630         Objects.requireNonNull(other);
 631         return implIsExportedOrOpen(pn, other, /*open*/true);
 632     }
 633 
 634     /**
 635      * Returns {@code true} if this module exports the given package
 636      * unconditionally.
 637      *
 638      * <p> This method always returns {@code true} when invoked on an unnamed
 639      * module. A package that is {@link #isOpen(String) opened} unconditionally
 640      * is considered exported unconditionally at run-time and so this method
 641      * returns {@code true} if the package is opened unconditionally. </p>
 642      *
 643      * <p> This method does not check if the given module reads this module. </p>
 644      *
 645      * @param  pn
 646      *         The package name
 647      *
 648      * @return {@code true} if this module exports the package unconditionally
 649      *
 650      * @see ModuleDescriptor#exports()
 651      */
 652     public boolean isExported(String pn) {
 653         Objects.requireNonNull(pn);
 654         return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/false);
 655     }
 656 
 657     /**
 658      * Returns {@code true} if this module has <em>opened</em> a package
 659      * unconditionally.
 660      *
 661      * <p> This method always returns {@code true} when invoked on an unnamed
 662      * module. Additionally, it always returns {@code true} when invoked on an
 663      * {@link ModuleDescriptor#isOpen open} module with a package in the
 664      * module. </p>
 665      *
 666      * <p> This method does not check if the given module reads this module. </p>
 667      *
 668      * @apiNote A package {@code p} opened to module {@code M} allows code in
 669      * {@code M} do {@linkplain java.lang.reflect.AccessibleObject#setAccessible(boolean)
 670      * deep reflection} on all types in the package.
 671      * Further, if {@code M} reads this module, it can obtain a
 672      * {@link java.lang.invoke.MethodHandles.Lookup Lookup} object that is allowed to
 673      * {@link java.lang.invoke.MethodHandles.Lookup#defineClass(byte[]) define classes}
 674      * in package {@code p}.
 675      *
 676      * @param  pn
 677      *         The package name
 678      *
 679      * @return {@code true} if this module has <em>opened</em> the package
 680      *         unconditionally
 681      *
 682      * @see ModuleDescriptor#opens()
 683      * @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
 684      * @see java.lang.invoke.MethodHandles#privateLookupIn
 685      */
 686     public boolean isOpen(String pn) {
 687         Objects.requireNonNull(pn);
 688         return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/true);
 689     }
 690 
 691 
 692     /**
 693      * Returns {@code true} if this module exports or opens the given package
 694      * to the given module. If the other module is {@code EVERYONE_MODULE} then
 695      * this method tests if the package is exported or opened unconditionally.
 696      */
 697     private boolean implIsExportedOrOpen(String pn, Module other, boolean open) {
 698         // all packages in unnamed modules are open
 699         if (!isNamed())
 700             return true;
 701 
 702         // all packages are exported/open to self
 703         if (other == this && descriptor.packages().contains(pn))
 704             return true;
 705 
 706         // all packages in open and automatic modules are open
 707         if (descriptor.isOpen() || descriptor.isAutomatic())
 708             return descriptor.packages().contains(pn);
 709 
 710         // exported/opened via module declaration/descriptor
 711         if (isStaticallyExportedOrOpen(pn, other, open))
 712             return true;
 713 
 714         // exported via addExports/addOpens
 715         if (isReflectivelyExportedOrOpen(pn, other, open))
 716             return true;
 717 
 718         // not exported or open to other
 719         return false;
 720     }
 721 
 722     /**
 723      * Returns {@code true} if this module exports or opens a package to
 724      * the given module via its module declaration or CLI options.
 725      */
 726     private boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
 727         // test if package is open to everyone or <other>
 728         Map<String, Set<Module>> openPackages = this.openPackages;
 729         if (openPackages != null && allows(openPackages.get(pn), other)) {
 730             return true;
 731         }
 732 
 733         if (!open) {
 734             // test package is exported to everyone or <other>
 735             Map<String, Set<Module>> exportedPackages = this.exportedPackages;
 736             if (exportedPackages != null && allows(exportedPackages.get(pn), other)) {
 737                 return true;
 738             }
 739         }
 740 
 741         return false;
 742     }
 743 
 744     /**
 745      * Returns {@code true} if targets is non-null and contains EVERYONE_MODULE
 746      * or the given module. Also returns true if the given module is an unnamed
 747      * module and targets contains ALL_UNNAMED_MODULE.
 748      */
 749     private boolean allows(Set<Module> targets, Module module) {
 750        if (targets != null) {
 751            if (targets.contains(EVERYONE_MODULE))
 752                return true;
 753            if (module != EVERYONE_MODULE) {
 754                if (targets.contains(module))
 755                    return true;
 756                if (!module.isNamed() && targets.contains(ALL_UNNAMED_MODULE))
 757                    return true;
 758            }
 759         }
 760         return false;
 761     }
 762 
 763     /**
 764      * Returns {@code true} if this module reflectively exports or opens the
 765      * given package to the given module.
 766      */
 767     private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
 768         // exported or open to all modules
 769         Map<String, Boolean> exports = ReflectionData.exports.get(this, EVERYONE_MODULE);
 770         if (exports != null) {
 771             Boolean b = exports.get(pn);
 772             if (b != null) {
 773                 boolean isOpen = b.booleanValue();
 774                 if (!open || isOpen) return true;
 775             }
 776         }
 777 
 778         if (other != EVERYONE_MODULE) {
 779 
 780             // exported or open to other
 781             exports = ReflectionData.exports.get(this, other);
 782             if (exports != null) {
 783                 Boolean b = exports.get(pn);
 784                 if (b != null) {
 785                     boolean isOpen = b.booleanValue();
 786                     if (!open || isOpen) return true;
 787                 }
 788             }
 789 
 790             // other is an unnamed module && exported or open to all unnamed
 791             if (!other.isNamed()) {
 792                 exports = ReflectionData.exports.get(this, ALL_UNNAMED_MODULE);
 793                 if (exports != null) {
 794                     Boolean b = exports.get(pn);
 795                     if (b != null) {
 796                         boolean isOpen = b.booleanValue();
 797                         if (!open || isOpen) return true;
 798                     }
 799                 }
 800             }
 801 
 802         }
 803 
 804         return false;
 805     }
 806 
 807     /**
 808      * Returns {@code true} if this module reflectively exports the
 809      * given package to the given module.
 810      */
 811     boolean isReflectivelyExported(String pn, Module other) {
 812         return isReflectivelyExportedOrOpen(pn, other, false);
 813     }
 814 
 815     /**
 816      * Returns {@code true} if this module reflectively opens the
 817      * given package to the given module.
 818      */
 819     boolean isReflectivelyOpened(String pn, Module other) {
 820         return isReflectivelyExportedOrOpen(pn, other, true);
 821     }
 822 
 823 
 824     /**
 825      * If the caller's module is this module then update this module to export
 826      * the given package to the given module.
 827      *
 828      * <p> This method has no effect if the package is already exported (or
 829      * <em>open</em>) to the given module. </p>
 830      *
 831      * @apiNote As specified in section {@jvms 5.4.3} of the <cite>The Java
 832      * Virtual Machine Specification </cite>, if an attempt to resolve a
 833      * symbolic reference fails because of a linkage error, then subsequent
 834      * attempts to resolve the reference always fail with the same error that
 835      * was thrown as a result of the initial resolution attempt.
 836      *
 837      * @param  pn
 838      *         The package name
 839      * @param  other
 840      *         The module
 841      *
 842      * @return this module
 843      *
 844      * @throws IllegalArgumentException
 845      *         If {@code pn} is {@code null}, or this is a named module and the
 846      *         package {@code pn} is not a package in this module
 847      * @throws IllegalCallerException
 848      *         If this is a named module and the caller's module is not this
 849      *         module
 850      *
 851      * @jvms 5.4.3 Resolution
 852      * @see #isExported(String,Module)
 853      */
 854     @CallerSensitive
 855     public Module addExports(String pn, Module other) {
 856         if (pn == null)
 857             throw new IllegalArgumentException("package is null");
 858         Objects.requireNonNull(other);
 859 
 860         if (isNamed()) {
 861             Module caller = getCallerModule(Reflection.getCallerClass());
 862             if (caller != this) {
 863                 throw new IllegalCallerException(caller + " != " + this);
 864             }
 865             implAddExportsOrOpens(pn, other, /*open*/false, /*syncVM*/true);
 866         }
 867 
 868         return this;
 869     }
 870 
 871     /**
 872      * If this module has <em>opened</em> a package to at least the caller
 873      * module then update this module to open the package to the given module.
 874      * Opening a package with this method allows all types in the package,
 875      * and all their members, not just public types and their public members,
 876      * to be reflected on by the given module when using APIs that support
 877      * private access or a way to bypass or suppress default Java language
 878      * access control checks.
 879      *
 880      * <p> This method has no effect if the package is already <em>open</em>
 881      * to the given module. </p>
 882      *
 883      * @apiNote This method can be used for cases where a <em>consumer
 884      * module</em> uses a qualified opens to open a package to an <em>API
 885      * module</em> but where the reflective access to the members of classes in
 886      * the consumer module is delegated to code in another module. Code in the
 887      * API module can use this method to open the package in the consumer module
 888      * to the other module.
 889      *
 890      * @param  pn
 891      *         The package name
 892      * @param  other
 893      *         The module
 894      *
 895      * @return this module
 896      *
 897      * @throws IllegalArgumentException
 898      *         If {@code pn} is {@code null}, or this is a named module and the
 899      *         package {@code pn} is not a package in this module
 900      * @throws IllegalCallerException
 901      *         If this is a named module and this module has not opened the
 902      *         package to at least the caller's module
 903      *
 904      * @see #isOpen(String,Module)
 905      * @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
 906      * @see java.lang.invoke.MethodHandles#privateLookupIn
 907      */
 908     @CallerSensitive
 909     public Module addOpens(String pn, Module other) {
 910         if (pn == null)
 911             throw new IllegalArgumentException("package is null");
 912         Objects.requireNonNull(other);
 913 
 914         if (isNamed()) {
 915             Module caller = getCallerModule(Reflection.getCallerClass());
 916             if (caller != this && (caller == null || !isOpen(pn, caller)))
 917                 throw new IllegalCallerException(pn + " is not open to " + caller);
 918             implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
 919         }
 920 
 921         return this;
 922     }
 923 
 924 
 925     /**
 926      * Updates this module to export a package unconditionally.
 927      *
 928      * @apiNote This method is for JDK tests only.
 929      */
 930     void implAddExports(String pn) {
 931         implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
 932     }
 933 
 934     /**
 935      * Updates this module to export a package to another module.
 936      *
 937      * @apiNote Used by Instrumentation::redefineModule and --add-exports
 938      */
 939     void implAddExports(String pn, Module other) {
 940         implAddExportsOrOpens(pn, other, false, true);
 941     }
 942 
 943     /**
 944      * Updates this module to export a package to all unnamed modules.
 945      *
 946      * @apiNote Used by the --add-exports command line option.
 947      */
 948     void implAddExportsToAllUnnamed(String pn) {
 949         implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
 950     }
 951 
 952     /**
 953      * Updates this export to export a package unconditionally without
 954      * notifying the VM.
 955      *
 956      * @apiNote This method is for VM white-box testing.
 957      */
 958     void implAddExportsNoSync(String pn) {
 959         implAddExportsOrOpens(pn.replace('/', '.'), Module.EVERYONE_MODULE, false, false);
 960     }
 961 
 962     /**
 963      * Updates a module to export a package to another module without
 964      * notifying the VM.
 965      *
 966      * @apiNote This method is for VM white-box testing.
 967      */
 968     void implAddExportsNoSync(String pn, Module other) {
 969         implAddExportsOrOpens(pn.replace('/', '.'), other, false, false);
 970     }
 971 
 972     /**
 973      * Updates this module to open a package unconditionally.
 974      *
 975      * @apiNote This method is for JDK tests only.
 976      */
 977     void implAddOpens(String pn) {
 978         implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
 979     }
 980 
 981     /**
 982      * Updates this module to open a package to another module.
 983      *
 984      * @apiNote Used by Instrumentation::redefineModule and --add-opens
 985      */
 986     void implAddOpens(String pn, Module other) {
 987         implAddExportsOrOpens(pn, other, true, true);
 988     }
 989 
 990     /**
 991      * Updates this module to open a package to all unnamed modules.
 992      *
 993      * @apiNote Used by the --add-opens command line option.
 994      */
 995     void implAddOpensToAllUnnamed(String pn) {
 996         implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
 997     }
 998 
 999     /**
1000      * Updates a module to export or open a module to another module.
1001      *
1002      * If {@code syncVM} is {@code true} then the VM is notified.
1003      */
1004     private void implAddExportsOrOpens(String pn,
1005                                        Module other,
1006                                        boolean open,
1007                                        boolean syncVM) {
1008         Objects.requireNonNull(other);
1009         Objects.requireNonNull(pn);
1010 
1011         // all packages are open in unnamed, open, and automatic modules
1012         if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
1013             return;
1014 
1015         // check if the package is already exported/open to other
1016         if (implIsExportedOrOpen(pn, other, open))
1017             return;
1018 
1019         // can only export a package in the module
1020         if (!descriptor.packages().contains(pn)) {
1021             throw new IllegalArgumentException("package " + pn
1022                                                + " not in contents");
1023         }
1024 
1025         // update VM first, just in case it fails
1026         if (syncVM) {
1027             if (other == EVERYONE_MODULE) {
1028                 addExportsToAll0(this, pn);
1029             } else if (other == ALL_UNNAMED_MODULE) {
1030                 addExportsToAllUnnamed0(this, pn);
1031             } else {
1032                 addExports0(this, pn, other);
1033             }
1034         }
1035 
1036         // add package name to exports if absent
1037         Map<String, Boolean> map = ReflectionData.exports
1038             .computeIfAbsent(this, other,
1039                              (m1, m2) -> new ConcurrentHashMap<>());
1040         if (open) {
1041             map.put(pn, Boolean.TRUE);  // may need to promote from FALSE to TRUE
1042         } else {
1043             map.putIfAbsent(pn, Boolean.FALSE);
1044         }
1045     }
1046 
1047     /**
1048      * Updates a module to open all packages in the given sets to all unnamed
1049      * modules.
1050      *
1051      * @apiNote Used during startup to open packages for illegal access.
1052      */
1053     void implAddOpensToAllUnnamed(Set<String> concealedPkgs, Set<String> exportedPkgs) {
1054         if (jdk.internal.misc.VM.isModuleSystemInited()) {
1055             throw new IllegalStateException("Module system already initialized");
1056         }
1057 
1058         // replace this module's openPackages map with a new map that opens
1059         // the packages to all unnamed modules.
1060         Map<String, Set<Module>> openPackages = this.openPackages;
1061         if (openPackages == null) {
1062             openPackages = HashMap.newHashMap(concealedPkgs.size() + exportedPkgs.size());
1063         } else {
1064             openPackages = new HashMap<>(openPackages);
1065         }
1066         implAddOpensToAllUnnamed(concealedPkgs, openPackages);
1067         implAddOpensToAllUnnamed(exportedPkgs, openPackages);
1068         this.openPackages = openPackages;
1069     }
1070 
1071     private void implAddOpensToAllUnnamed(Set<String> pkgs, Map<String, Set<Module>> openPackages) {
1072         for (String pn : pkgs) {
1073             Set<Module> prev = openPackages.putIfAbsent(pn, ALL_UNNAMED_MODULE_SET);
1074             if (prev != null) {
1075                 prev.add(ALL_UNNAMED_MODULE);
1076             }
1077 
1078             // update VM to export the package
1079             addExportsToAllUnnamed0(this, pn);
1080         }
1081     }
1082 
1083     // -- services --
1084 
1085     /**
1086      * If the caller's module is this module then update this module to add a
1087      * service dependence on the given service type. This method is intended
1088      * for use by frameworks that invoke {@link java.util.ServiceLoader
1089      * ServiceLoader} on behalf of other modules or where the framework is
1090      * passed a reference to the service type by other code. This method is
1091      * a no-op when invoked on an unnamed module or an automatic module.
1092      *
1093      * <p> This method does not cause {@link Configuration#resolveAndBind
1094      * resolveAndBind} to be re-run. </p>
1095      *
1096      * @param  service
1097      *         The service type
1098      *
1099      * @return this module
1100      *
1101      * @throws IllegalCallerException
1102      *         If this is a named module and the caller's module is not this
1103      *         module
1104      *
1105      * @see #canUse(Class)
1106      * @see ModuleDescriptor#uses()
1107      */
1108     @CallerSensitive
1109     public Module addUses(Class<?> service) {
1110         Objects.requireNonNull(service);
1111 
1112         if (isNamed() && !descriptor.isAutomatic()) {
1113             Module caller = getCallerModule(Reflection.getCallerClass());
1114             if (caller != this) {
1115                 throw new IllegalCallerException(caller + " != " + this);
1116             }
1117             implAddUses(service);
1118         }
1119 
1120         return this;
1121     }
1122 
1123     /**
1124      * Update this module to add a service dependence on the given service
1125      * type.
1126      */
1127     void implAddUses(Class<?> service) {
1128         if (!canUse(service)) {
1129             ReflectionData.uses.putIfAbsent(this, service, Boolean.TRUE);
1130         }
1131     }
1132 
1133 
1134     /**
1135      * Indicates if this module has a service dependence on the given service
1136      * type. This method always returns {@code true} when invoked on an unnamed
1137      * module or an automatic module.
1138      *
1139      * @param  service
1140      *         The service type
1141      *
1142      * @return {@code true} if this module uses service type {@code st}
1143      *
1144      * @see #addUses(Class)
1145      */
1146     public boolean canUse(Class<?> service) {
1147         Objects.requireNonNull(service);
1148 
1149         if (!isNamed())
1150             return true;
1151 
1152         if (descriptor.isAutomatic())
1153             return true;
1154 
1155         // uses was declared
1156         if (descriptor.uses().contains(service.getName()))
1157             return true;
1158 
1159         // uses added via addUses
1160         return ReflectionData.uses.containsKeyPair(this, service);
1161     }
1162 
1163 
1164 
1165     // -- packages --
1166 
1167     /**
1168      * Returns the set of package names for the packages in this module.
1169      *
1170      * <p> For named modules, the returned set contains an element for each
1171      * package in the module. </p>
1172      *
1173      * <p> For unnamed modules, the returned set contains an element for
1174      * each package that {@link ClassLoader#getDefinedPackages() has been defined}
1175      * in the unnamed module.</p>
1176      *
1177      * @return the set of the package names of the packages in this module
1178      */
1179     public Set<String> getPackages() {
1180         if (isNamed()) {
1181             return descriptor.packages();
1182         } else {
1183             // unnamed module
1184             Stream<Package> packages;
1185             if (loader == null) {
1186                 packages = BootLoader.packages();
1187             } else {
1188                 packages = loader.packages();
1189             }
1190             return packages.filter(p -> p.module() == this)
1191                            .map(Package::getName).collect(Collectors.toSet());
1192         }
1193     }
1194 
1195     // -- creating Module objects --
1196 
1197     /**
1198      * Defines all module in a configuration to the runtime.
1199      *
1200      * @return a map of module name to runtime {@code Module}
1201      *
1202      * @throws IllegalArgumentException
1203      *         If the function maps a module to the null or platform class loader
1204      * @throws IllegalStateException
1205      *         If the module cannot be defined to the VM or its packages overlap
1206      *         with another module mapped to the same class loader
1207      */
1208     static Map<String, Module> defineModules(Configuration cf,
1209                                              Function<String, ClassLoader> clf,
1210                                              ModuleLayer layer)
1211     {
1212         boolean isBootLayer = (ModuleLayer.boot() == null);
1213 
1214         int numModules = cf.modules().size();
1215         Map<String, Module> nameToModule = HashMap.newHashMap(numModules);
1216 
1217         // to avoid repeated lookups and reduce iteration overhead, we create
1218         // arrays holding correlated information about each module.
1219         ResolvedModule[] resolvedModules = new ResolvedModule[numModules];
1220         Module[] modules = new Module[numModules];
1221         ClassLoader[] classLoaders = new ClassLoader[numModules];
1222 
1223         resolvedModules = cf.modules().toArray(resolvedModules);
1224 
1225         // record that we want to bind the layer to non-boot and non-platform
1226         // module loaders as a final step
1227         HashSet<ClassLoader> toBindLoaders = new HashSet<>(4);
1228         boolean hasPlatformModules = false;
1229 
1230         // map each module to a class loader
1231         ClassLoader pcl = ClassLoaders.platformClassLoader();
1232         boolean isModuleLoaderMapper = ModuleLoaderMap.isBuiltinMapper(clf);
1233 
1234         for (int index = 0; index < numModules; index++) {
1235             String name = resolvedModules[index].name();
1236             ClassLoader loader = clf.apply(name);
1237 
1238             if (loader == null || loader == pcl) {
1239                 if (!isModuleLoaderMapper) {
1240                     throw new IllegalArgumentException("loader can't be 'null'"
1241                             + " or the platform class loader");
1242                 }
1243                 hasPlatformModules = true;
1244             } else {
1245                 toBindLoaders.add(loader);
1246             }
1247 
1248             classLoaders[index] = loader;
1249         }
1250 
1251         // define each module in the configuration to the VM
1252         for (int index = 0; index < numModules; index++) {
1253             ModuleReference mref = resolvedModules[index].reference();
1254             ModuleDescriptor descriptor = mref.descriptor();
1255             String name = descriptor.name();
1256             ClassLoader loader = classLoaders[index];
1257             Module m;
1258             if (loader == null && name.equals("java.base")) {
1259                 // java.base is already defined to the VM
1260                 m = Object.class.getModule();
1261             } else {
1262                 URI uri = mref.location().orElse(null);
1263                 m = new Module(layer, loader, descriptor, uri);
1264             }
1265             nameToModule.put(name, m);
1266             modules[index] = m;
1267         }
1268 
1269         // setup readability and exports/opens
1270         for (int index = 0; index < numModules; index++) {
1271             ResolvedModule resolvedModule = resolvedModules[index];
1272             ModuleReference mref = resolvedModule.reference();
1273             ModuleDescriptor descriptor = mref.descriptor();
1274             Module m = modules[index];
1275 
1276             // reads
1277             Set<Module> reads = new HashSet<>();
1278 
1279             // name -> source Module when in parent layer
1280             Map<String, Module> nameToSource = Map.of();
1281 
1282             for (ResolvedModule other : resolvedModule.reads()) {
1283                 Module m2 = null;
1284                 if (other.configuration() == cf) {
1285                     // this configuration
1286                     m2 = nameToModule.get(other.name());
1287                     assert m2 != null;
1288                 } else {
1289                     // parent layer
1290                     for (ModuleLayer parent: layer.parents()) {
1291                         m2 = findModule(parent, other);
1292                         if (m2 != null)
1293                             break;
1294                     }
1295                     assert m2 != null;
1296                     if (nameToSource.isEmpty())
1297                         nameToSource = new HashMap<>();
1298                     nameToSource.put(other.name(), m2);
1299                 }
1300                 reads.add(m2);
1301 
1302                 // update VM view
1303                 addReads0(m, m2);
1304             }
1305             m.reads = reads;
1306 
1307             // automatic modules read all unnamed modules
1308             if (descriptor.isAutomatic()) {
1309                 m.implAddReads(ALL_UNNAMED_MODULE, true);
1310             }
1311 
1312             // exports and opens, skipped for open and automatic
1313             if (!descriptor.isOpen() && !descriptor.isAutomatic()) {
1314                 if (isBootLayer && descriptor.opens().isEmpty()) {
1315                     // no open packages, no qualified exports to modules in parent layers
1316                     initExports(m, nameToModule);
1317                 } else {
1318                     initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
1319                 }
1320             }
1321         }
1322 
1323         // if there are modules defined to the boot or platform class loaders
1324         // then register the modules in the class loader's services catalog
1325         if (hasPlatformModules) {
1326             ServicesCatalog bootCatalog = BootLoader.getServicesCatalog();
1327             ServicesCatalog pclCatalog = ServicesCatalog.getServicesCatalog(pcl);
1328             for (int index = 0; index < numModules; index++) {
1329                 ResolvedModule resolvedModule = resolvedModules[index];
1330                 ModuleReference mref = resolvedModule.reference();
1331                 ModuleDescriptor descriptor = mref.descriptor();
1332                 if (!descriptor.provides().isEmpty()) {
1333                     Module m = modules[index];
1334                     ClassLoader loader = classLoaders[index];
1335                     if (loader == null) {
1336                         bootCatalog.register(m);
1337                     } else if (loader == pcl) {
1338                         pclCatalog.register(m);
1339                     }
1340                 }
1341             }
1342         }
1343 
1344         // record that there is a layer with modules defined to the class loader
1345         for (ClassLoader loader : toBindLoaders) {
1346             layer.bindToLoader(loader);
1347         }
1348 
1349         return nameToModule;
1350     }
1351 
1352     /**
1353      * Find the runtime Module corresponding to the given ResolvedModule
1354      * in the given parent layer (or its parents).
1355      */
1356     private static Module findModule(ModuleLayer parent,
1357                                      ResolvedModule resolvedModule) {
1358         Configuration cf = resolvedModule.configuration();
1359         String dn = resolvedModule.name();
1360         return parent.layers()
1361                 .filter(l -> l.configuration() == cf)
1362                 .findAny()
1363                 .map(layer -> {
1364                     Optional<Module> om = layer.findModule(dn);
1365                     assert om.isPresent() : dn + " not found in layer";
1366                     Module m = om.get();
1367                     assert m.getLayer() == layer : m + " not in expected layer";
1368                     return m;
1369                 })
1370                 .orElse(null);
1371     }
1372 
1373     /**
1374      * Initialize/setup a module's exports.
1375      *
1376      * @param m the module
1377      * @param nameToModule map of module name to Module (for qualified exports)
1378      */
1379     private static void initExports(Module m, Map<String, Module> nameToModule) {
1380         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1381 
1382         for (Exports exports : m.getDescriptor().exports()) {
1383             String source = exports.source();
1384             if (exports.isQualified()) {
1385                 // qualified exports
1386                 Set<Module> targets = new HashSet<>();
1387                 for (String target : exports.targets()) {
1388                     Module m2 = nameToModule.get(target);
1389                     if (m2 != null) {
1390                         addExports0(m, source, m2);
1391                         targets.add(m2);
1392                     }
1393                 }
1394                 if (!targets.isEmpty()) {
1395                     exportedPackages.put(source, targets);
1396                 }
1397             } else {
1398                 // unqualified exports
1399                 addExportsToAll0(m, source);
1400                 exportedPackages.put(source, EVERYONE_SET);
1401             }
1402         }
1403 
1404         if (!exportedPackages.isEmpty())
1405             m.exportedPackages = exportedPackages;
1406     }
1407 
1408     /**
1409      * Initialize/setup a module's exports.
1410      *
1411      * @param m the module
1412      * @param nameToSource map of module name to Module for modules that m reads
1413      * @param nameToModule map of module name to Module for modules in the layer
1414      *                     under construction
1415      * @param parents the parent layers
1416      */
1417     private static void initExportsAndOpens(Module m,
1418                                             Map<String, Module> nameToSource,
1419                                             Map<String, Module> nameToModule,
1420                                             List<ModuleLayer> parents) {
1421         ModuleDescriptor descriptor = m.getDescriptor();
1422         Map<String, Set<Module>> openPackages = new HashMap<>();
1423         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1424 
1425         // process the open packages first
1426         for (Opens opens : descriptor.opens()) {
1427             String source = opens.source();
1428 
1429             if (opens.isQualified()) {
1430                 // qualified opens
1431                 Set<Module> targets = new HashSet<>();
1432                 for (String target : opens.targets()) {
1433                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1434                     if (m2 != null) {
1435                         addExports0(m, source, m2);
1436                         targets.add(m2);
1437                     }
1438                 }
1439                 if (!targets.isEmpty()) {
1440                     openPackages.put(source, targets);
1441                 }
1442             } else {
1443                 // unqualified opens
1444                 addExportsToAll0(m, source);
1445                 openPackages.put(source, EVERYONE_SET);
1446             }
1447         }
1448 
1449         // next the exports, skipping exports when the package is open
1450         for (Exports exports : descriptor.exports()) {
1451             String source = exports.source();
1452 
1453             // skip export if package is already open to everyone
1454             Set<Module> openToTargets = openPackages.get(source);
1455             if (openToTargets != null && openToTargets.contains(EVERYONE_MODULE))
1456                 continue;
1457 
1458             if (exports.isQualified()) {
1459                 // qualified exports
1460                 Set<Module> targets = new HashSet<>();
1461                 for (String target : exports.targets()) {
1462                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1463                     if (m2 != null) {
1464                         // skip qualified export if already open to m2
1465                         if (openToTargets == null || !openToTargets.contains(m2)) {
1466                             addExports0(m, source, m2);
1467                             targets.add(m2);
1468                         }
1469                     }
1470                 }
1471                 if (!targets.isEmpty()) {
1472                     exportedPackages.put(source, targets);
1473                 }
1474             } else {
1475                 // unqualified exports
1476                 addExportsToAll0(m, source);
1477                 exportedPackages.put(source, EVERYONE_SET);
1478             }
1479         }
1480 
1481         if (!openPackages.isEmpty())
1482             m.openPackages = openPackages;
1483         if (!exportedPackages.isEmpty())
1484             m.exportedPackages = exportedPackages;
1485     }
1486 
1487     /**
1488      * Find the runtime Module with the given name. The module name is the
1489      * name of a target module in a qualified exports or opens directive.
1490      *
1491      * @param target The target module to find
1492      * @param nameToSource The modules in parent layers that are read
1493      * @param nameToModule The modules in the layer under construction
1494      * @param parents The parent layers
1495      */
1496     private static Module findModule(String target,
1497                                      Map<String, Module> nameToSource,
1498                                      Map<String, Module> nameToModule,
1499                                      List<ModuleLayer> parents) {
1500         Module m = nameToSource.get(target);
1501         if (m == null) {
1502             m = nameToModule.get(target);
1503             if (m == null) {
1504                 for (ModuleLayer parent : parents) {
1505                     m = parent.findModule(target).orElse(null);
1506                     if (m != null) break;
1507                 }
1508             }
1509         }
1510         return m;
1511     }
1512 
1513 
1514     // -- annotations --
1515 
1516     /**
1517      * {@inheritDoc}
1518      * This method returns {@code null} when invoked on an unnamed module.
1519      *
1520      * <p> Note that any annotation returned by this method is a
1521      * declaration annotation.
1522      */
1523     @Override
1524     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1525         return moduleInfoClass().getDeclaredAnnotation(annotationClass);
1526     }
1527 
1528     /**
1529      * {@inheritDoc}
1530      * This method returns an empty array when invoked on an unnamed module.
1531      *
1532      * <p> Note that any annotations returned by this method are
1533      * declaration annotations.
1534      */
1535     @Override
1536     public Annotation[] getAnnotations() {
1537         return moduleInfoClass().getAnnotations();
1538     }
1539 
1540     /**
1541      * {@inheritDoc}
1542      * This method returns an empty array when invoked on an unnamed module.
1543      *
1544      * <p> Note that any annotations returned by this method are
1545      * declaration annotations.
1546      */
1547     @Override
1548     public Annotation[] getDeclaredAnnotations() {
1549         return moduleInfoClass().getDeclaredAnnotations();
1550     }
1551 
1552     // cached class file with annotations
1553     private volatile Class<?> moduleInfoClass;
1554 
1555     @SuppressWarnings("removal")
1556     private Class<?> moduleInfoClass() {
1557         Class<?> clazz = this.moduleInfoClass;
1558         if (clazz != null)
1559             return clazz;
1560 
1561         synchronized (this) {
1562             clazz = this.moduleInfoClass;
1563             if (clazz == null) {
1564                 if (isNamed()) {
1565                     PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass;
1566                     clazz = AccessController.doPrivileged(pa);
1567                 }
1568                 if (clazz == null) {
1569                     class DummyModuleInfo { }
1570                     clazz = DummyModuleInfo.class;
1571                 }
1572                 this.moduleInfoClass = clazz;
1573             }
1574             return clazz;
1575         }
1576     }
1577 
1578     private Class<?> loadModuleInfoClass() {
1579         Class<?> clazz = null;
1580         try (InputStream in = getResourceAsStream("module-info.class")) {
1581             if (in != null)
1582                 clazz = loadModuleInfoClass(in);
1583         } catch (Exception ignore) { }
1584         return clazz;
1585     }
1586 
1587     /**
1588      * Loads module-info.class as a package-private interface in a class loader
1589      * that is a child of this module's class loader.
1590      */
1591     private Class<?> loadModuleInfoClass(InputStream in) throws IOException {
1592         final String MODULE_INFO = "module-info";
1593         var cc = Classfile.of(Classfile.ConstantPoolSharingOption.NEW_POOL);
1594         byte[] bytes = cc.transform(cc.parse(in.readAllBytes()), (clb, cle) -> {
1595             switch (cle) {
1596                 case AccessFlags af -> clb.withFlags(AccessFlag.INTERFACE,
1597                         AccessFlag.ABSTRACT, AccessFlag.SYNTHETIC);
1598                 // keep annotations
1599                 case RuntimeVisibleAnnotationsAttribute a -> clb.with(a);
1600                 // drop non-annotation attributes
1601                 case Attribute<?> a -> {}
1602                 default -> clb.with(cle);
1603             }});
1604         ClassLoader cl = new ClassLoader(loader) {
1605             @Override
1606             protected Class<?> findClass(String cn)throws ClassNotFoundException {
1607                 if (cn.equals(MODULE_INFO)) {
1608                     return super.defineClass(cn, bytes, 0, bytes.length);
1609                 } else {
1610                     throw new ClassNotFoundException(cn);
1611                 }
1612             }
1613             @Override
1614             protected Class<?> loadClass(String cn, boolean resolve)
1615                 throws ClassNotFoundException
1616             {
1617                 synchronized (getClassLoadingLock(cn)) {
1618                     Class<?> c = findLoadedClass(cn);
1619                     if (c == null) {
1620                         if (cn.equals(MODULE_INFO)) {
1621                             c = findClass(cn);
1622                         } else {
1623                             c = super.loadClass(cn, resolve);
1624                         }
1625                     }
1626                     if (resolve)
1627                         resolveClass(c);
1628                     return c;
1629                 }
1630             }
1631         };
1632 
1633         try {
1634             return cl.loadClass(MODULE_INFO);
1635         } catch (ClassNotFoundException e) {
1636             throw new InternalError(e);
1637         }
1638     }
1639 
1640 
1641     // -- misc --
1642 
1643 
1644     /**
1645      * Returns an input stream for reading a resource in this module.
1646      * The {@code name} parameter is a {@code '/'}-separated path name that
1647      * identifies the resource. As with {@link Class#getResourceAsStream
1648      * Class.getResourceAsStream}, this method delegates to the module's class
1649      * loader {@link ClassLoader#findResource(String,String)
1650      * findResource(String,String)} method, invoking it with the module name
1651      * (or {@code null} when the module is unnamed) and the name of the
1652      * resource. If the resource name has a leading slash then it is dropped
1653      * before delegation.
1654      *
1655      * <p> A resource in a named module may be <em>encapsulated</em> so that
1656      * it cannot be located by code in other modules. Whether a resource can be
1657      * located or not is determined as follows: </p>
1658      *
1659      * <ul>
1660      *     <li> If the resource name ends with  "{@code .class}" then it is not
1661      *     encapsulated. </li>
1662      *
1663      *     <li> A <em>package name</em> is derived from the resource name. If
1664      *     the package name is a {@linkplain #getPackages() package} in the
1665      *     module then the resource can only be located by the caller of this
1666      *     method when the package is {@linkplain #isOpen(String,Module) open}
1667      *     to at least the caller's module. If the resource is not in a
1668      *     package in the module then the resource is not encapsulated. </li>
1669      * </ul>
1670      *
1671      * <p> In the above, the <em>package name</em> for a resource is derived
1672      * from the subsequence of characters that precedes the last {@code '/'} in
1673      * the name and then replacing each {@code '/'} character in the subsequence
1674      * with {@code '.'}. A leading slash is ignored when deriving the package
1675      * name. As an example, the package name derived for a resource named
1676      * "{@code a/b/c/foo.properties}" is "{@code a.b.c}". A resource name
1677      * with the name "{@code META-INF/MANIFEST.MF}" is never encapsulated
1678      * because "{@code META-INF}" is not a legal package name. </p>
1679      *
1680      * <p> This method returns {@code null} if the resource is not in this
1681      * module, the resource is encapsulated and cannot be located by the caller,
1682      * or access to the resource is denied by the security manager. </p>
1683      *
1684      * @param  name
1685      *         The resource name
1686      *
1687      * @return An input stream for reading the resource or {@code null}
1688      *
1689      * @throws IOException
1690      *         If an I/O error occurs
1691      *
1692      * @see Class#getResourceAsStream(String)
1693      */
1694     @CallerSensitive
1695     public InputStream getResourceAsStream(String name) throws IOException {
1696         if (name.startsWith("/")) {
1697             name = name.substring(1);
1698         }
1699 
1700         if (isNamed() && Resources.canEncapsulate(name)) {
1701             Module caller = getCallerModule(Reflection.getCallerClass());
1702             if (caller != this && caller != Object.class.getModule()) {
1703                 String pn = Resources.toPackageName(name);
1704                 if (getPackages().contains(pn)) {
1705                     if (caller == null) {
1706                         if (!isOpen(pn)) {
1707                             return null;
1708                         }
1709                     } else if (!isOpen(pn, caller)) {
1710                         // package not open to caller
1711                         return null;
1712                     }
1713                 }
1714             }
1715         }
1716 
1717         String mn = this.name;
1718 
1719         // special-case built-in class loaders to avoid URL connection
1720         if (loader == null) {
1721             return BootLoader.findResourceAsStream(mn, name);
1722         } else if (loader instanceof BuiltinClassLoader) {
1723             return ((BuiltinClassLoader) loader).findResourceAsStream(mn, name);
1724         }
1725 
1726         // locate resource in module
1727         URL url = loader.findResource(mn, name);
1728         if (url != null) {
1729             try {
1730                 return url.openStream();
1731             } catch (SecurityException e) { }
1732         }
1733 
1734         return null;
1735     }
1736 
1737     /**
1738      * Returns the string representation of this module. For a named module,
1739      * the representation is the string {@code "module"}, followed by a space,
1740      * and then the module name. For an unnamed module, the representation is
1741      * the string {@code "unnamed module"}, followed by a space, and then an
1742      * implementation specific string that identifies the unnamed module.
1743      *
1744      * @return The string representation of this module
1745      */
1746     @Override
1747     public String toString() {
1748         if (isNamed()) {
1749             return "module " + name;
1750         } else {
1751             String id = Integer.toHexString(System.identityHashCode(this));
1752             return "unnamed module @" + id;
1753         }
1754     }
1755 
1756     /**
1757      * Returns the module that a given caller class is a member of. Returns
1758      * {@code null} if the caller is {@code null}.
1759      */
1760     private Module getCallerModule(Class<?> caller) {
1761         return (caller != null) ? caller.getModule() : null;
1762     }
1763 
1764 
1765     // -- native methods --
1766 
1767     // JVM_DefineModule
1768     private static native void defineModule0(Module module,
1769                                              boolean isOpen,
1770                                              String version,
1771                                              String location,
1772                                              Object[] pns);
1773 
1774     // JVM_AddReadsModule
1775     private static native void addReads0(Module from, Module to);
1776 
1777     // JVM_AddModuleExports
1778     private static native void addExports0(Module from, String pn, Module to);
1779 
1780     // JVM_AddModuleExportsToAll
1781     private static native void addExportsToAll0(Module from, String pn);
1782 
1783     // JVM_AddModuleExportsToAllUnnamed
1784     private static native void addExportsToAllUnnamed0(Module from, String pn);
1785 }