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