1 /*
   2  * Copyright (c) 2014, 2016, 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.reflect;
  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.net.URI;
  39 import java.net.URL;
  40 import java.security.AccessController;
  41 import java.security.PrivilegedAction;
  42 import java.util.Collections;
  43 import java.util.HashMap;
  44 import java.util.HashSet;
  45 import java.util.Map;
  46 import java.util.Objects;
  47 import java.util.Optional;
  48 import java.util.Set;
  49 import java.util.concurrent.ConcurrentHashMap;
  50 import java.util.function.Function;
  51 import java.util.stream.Stream;
  52 
  53 import jdk.internal.loader.BuiltinClassLoader;
  54 import jdk.internal.loader.BootLoader;
  55 import jdk.internal.loader.ResourceHelper;
  56 import jdk.internal.misc.JavaLangAccess;
  57 import jdk.internal.misc.JavaLangReflectModuleAccess;
  58 import jdk.internal.misc.SharedSecrets;
  59 import jdk.internal.module.ServicesCatalog;
  60 import jdk.internal.org.objectweb.asm.AnnotationVisitor;
  61 import jdk.internal.org.objectweb.asm.Attribute;
  62 import jdk.internal.org.objectweb.asm.ClassReader;
  63 import jdk.internal.org.objectweb.asm.ClassVisitor;
  64 import jdk.internal.org.objectweb.asm.ClassWriter;
  65 import jdk.internal.org.objectweb.asm.Opcodes;
  66 import jdk.internal.reflect.CallerSensitive;
  67 import jdk.internal.reflect.Reflection;
  68 import sun.security.util.SecurityConstants;
  69 
  70 /**
  71  * Represents a run-time module, either {@link #isNamed() named} or unnamed.
  72  *
  73  * <p> Named modules have a {@link #getName() name} and are constructed by the
  74  * Java Virtual Machine when a graph of modules is defined to the Java virtual
  75  * machine to create a module {@link Layer Layer}. </p>
  76  *
  77  * <p> An unnamed module does not have a name. There is an unnamed module
  78  * per {@link ClassLoader ClassLoader} that is obtained by invoking the class
  79  * loader's {@link ClassLoader#getUnnamedModule() getUnnamedModule} method. The
  80  * {@link Class#getModule() getModule} method of all types defined by a class
  81  * loader that are not in a named module return the class loader's unnamed
  82  * module. </p>
  83  *
  84  * <p> The package names that are parameters or returned by methods defined in
  85  * this class are the fully-qualified names of the packages as defined in
  86  * section 6.5.3 of <cite>The Java&trade; Language Specification </cite>, for
  87  * example, {@code "java.lang"}. </p>
  88  *
  89  * <p> Unless otherwise specified, passing a {@code null} argument to a method
  90  * in this class causes a {@link NullPointerException NullPointerException} to
  91  * be thrown. </p>
  92  *
  93  * @since 9
  94  * @see java.lang.Class#getModule
  95  */
  96 
  97 public final class Module implements AnnotatedElement {
  98 
  99     // the layer that contains this module, can be null
 100     private final Layer layer;
 101 
 102     // module name and loader, these fields are read by VM
 103     private final String name;
 104     private final ClassLoader loader;
 105 
 106     // the module descriptor
 107     private final ModuleDescriptor descriptor;
 108 
 109 
 110     /**
 111      * Creates a new named Module. The resulting Module will be defined to the
 112      * VM but will not read any other modules, will not have any exports setup
 113      * and will not be registered in the service catalog.
 114      */
 115     private Module(Layer layer,
 116                    ClassLoader loader,
 117                    ModuleDescriptor descriptor,
 118                    URI uri)
 119     {
 120         this.layer = layer;
 121         this.name = descriptor.name();
 122         this.loader = loader;
 123         this.descriptor = descriptor;
 124 
 125         // define module to VM
 126 
 127         boolean isOpen = descriptor.isOpen();
 128         Version version = descriptor.version().orElse(null);
 129         String vs = Objects.toString(version, null);
 130         String loc = Objects.toString(uri, null);
 131         Set<String> packages = descriptor.packages();
 132         int n = packages.size();
 133         String[] array = new String[n];
 134         int i = 0;
 135         for (String pn : packages) {
 136             array[i++] = pn.replace('.', '/');
 137         }
 138         defineModule0(this, isOpen, vs, loc, array);
 139     }
 140 
 141 
 142     /**
 143      * Create the unnamed Module for the given ClassLoader.
 144      *
 145      * @see ClassLoader#getUnnamedModule
 146      */
 147     private Module(ClassLoader loader) {
 148         this.layer = null;
 149         this.name = null;
 150         this.loader = loader;
 151         this.descriptor = null;
 152     }
 153 
 154 
 155     /**
 156      * Creates a named module but without defining the module to the VM.
 157      *
 158      * @apiNote This constructor is for VM white-box testing.
 159      */
 160     Module(ClassLoader loader, ModuleDescriptor descriptor) {
 161         this.layer = null;
 162         this.name = descriptor.name();
 163         this.loader = loader;
 164         this.descriptor = descriptor;
 165     }
 166 
 167 
 168 
 169     /**
 170      * Returns {@code true} if this module is a named module.
 171      *
 172      * @return {@code true} if this is a named module
 173      *
 174      * @see ClassLoader#getUnnamedModule()
 175      */
 176     public boolean isNamed() {
 177         return name != null;
 178     }
 179 
 180     /**
 181      * Returns the module name or {@code null} if this module is an unnamed
 182      * module.
 183      *
 184      * @return The module name
 185      */
 186     public String getName() {
 187         return name;
 188     }
 189 
 190     /**
 191      * Returns the {@code ClassLoader} for this module.
 192      *
 193      * <p> If there is a security manager then its {@code checkPermission}
 194      * method if first called with a {@code RuntimePermission("getClassLoader")}
 195      * permission to check that the caller is allowed to get access to the
 196      * class loader. </p>
 197      *
 198      * @return The class loader for this module
 199      *
 200      * @throws SecurityException
 201      *         If denied by the security manager
 202      */
 203     public ClassLoader getClassLoader() {
 204         SecurityManager sm = System.getSecurityManager();
 205         if (sm != null) {
 206             sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 207         }
 208         return loader;
 209     }
 210 
 211     /**
 212      * Returns the module descriptor for this module or {@code null} if this
 213      * module is an unnamed module.
 214      *
 215      * @return The module descriptor for this module
 216      */
 217     public ModuleDescriptor getDescriptor() {
 218         return descriptor;
 219     }
 220 
 221     /**
 222      * Returns the layer that contains this module or {@code null} if this
 223      * module is not in a layer.
 224      *
 225      * A module {@code Layer} contains named modules and therefore this
 226      * method always returns {@code null} when invoked on an unnamed module.
 227      *
 228      * <p> <a href="Proxy.html#dynamicmodule">Dynamic modules</a> are named
 229      * modules that are generated at runtime. A dynamic module may or may
 230      * not be in a module Layer. </p>
 231      *
 232      * @return The layer that contains this module
 233      *
 234      * @see Proxy
 235      */
 236     public Layer getLayer() {
 237         if (isNamed()) {
 238             Layer layer = this.layer;
 239             if (layer != null)
 240                 return layer;
 241 
 242             // special-case java.base as it is created before the boot Layer
 243             if (loader == null && name.equals("java.base")) {
 244                 return SharedSecrets.getJavaLangAccess().getBootLayer();
 245             }
 246         }
 247 
 248         return null;
 249     }
 250 
 251 
 252     // --
 253 
 254     // special Module to mean "all unnamed modules"
 255     private static final Module ALL_UNNAMED_MODULE = new Module(null);
 256 
 257     // special Module to mean "everyone"
 258     private static final Module EVERYONE_MODULE = new Module(null);
 259 
 260     // set contains EVERYONE_MODULE, used when a package is opened or
 261     // exported unconditionally
 262     private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
 263 
 264 
 265     // -- readability --
 266 
 267     // the modules that this module reads
 268     private volatile Set<Module> reads;
 269 
 270     // additional module (2nd key) that some module (1st key) reflectively reads
 271     private static final WeakPairMap<Module, Module, Boolean> reflectivelyReads
 272         = new WeakPairMap<>();
 273 
 274 
 275     /**
 276      * Indicates if this module reads the given module. This method returns
 277      * {@code true} if invoked to test if this module reads itself. It also
 278      * returns {@code true} if invoked on an unnamed module (as unnamed
 279      * modules read all modules).
 280      *
 281      * @param  other
 282      *         The other module
 283      *
 284      * @return {@code true} if this module reads {@code other}
 285      *
 286      * @see #addReads(Module)
 287      */
 288     public boolean canRead(Module other) {
 289         Objects.requireNonNull(other);
 290 
 291         // an unnamed module reads all modules
 292         if (!this.isNamed())
 293             return true;
 294 
 295         // all modules read themselves
 296         if (other == this)
 297             return true;
 298 
 299         // check if this module reads other
 300         if (other.isNamed()) {
 301             Set<Module> reads = this.reads; // volatile read
 302             if (reads != null && reads.contains(other))
 303                 return true;
 304         }
 305 
 306         // check if this module reads the other module reflectively
 307         if (reflectivelyReads.containsKeyPair(this, other))
 308             return true;
 309 
 310         // if other is an unnamed module then check if this module reads
 311         // all unnamed modules
 312         if (!other.isNamed()
 313             && reflectivelyReads.containsKeyPair(this, ALL_UNNAMED_MODULE))
 314             return true;
 315 
 316         return false;
 317     }
 318 
 319     /**
 320      * If the caller's module is this module then update this module to read
 321      * the given module.
 322      *
 323      * This method is a no-op if {@code other} is this module (all modules read
 324      * themselves), this module is an unnamed module (as unnamed modules read
 325      * all modules), or this module already reads {@code other}.
 326      *
 327      * @implNote <em>Read edges</em> added by this method are <em>weak</em> and
 328      * do not prevent {@code other} from being GC'ed when this module is
 329      * strongly reachable.
 330      *
 331      * @param  other
 332      *         The other module
 333      *
 334      * @return this module
 335      *
 336      * @throws IllegalStateException
 337      *         If this is a named module and the caller is not this module
 338      *
 339      * @see #canRead
 340      */
 341     @CallerSensitive
 342     public Module addReads(Module other) {
 343         Objects.requireNonNull(other);
 344         if (this.isNamed()) {
 345             Module caller = Reflection.getCallerClass().getModule();
 346             if (caller != this) {
 347                 throw new IllegalStateException(caller + " != " + this);
 348             }
 349             implAddReads(other, true);
 350         }
 351         return this;
 352     }
 353 
 354     /**
 355      * Updates this module to read another module.
 356      *
 357      * @apiNote This method is for Proxy use and white-box testing.
 358      */
 359     void implAddReads(Module other) {
 360         implAddReads(other, true);
 361     }
 362 
 363     /**
 364      * Updates this module to read another module without notifying the VM.
 365      *
 366      * @apiNote This method is for VM white-box testing.
 367      */
 368     void implAddReadsNoSync(Module other) {
 369         implAddReads(other, false);
 370     }
 371 
 372     /**
 373      * Makes the given {@code Module} readable to this module.
 374      *
 375      * If {@code syncVM} is {@code true} then the VM is notified.
 376      */
 377     private void implAddReads(Module other, boolean syncVM) {
 378         Objects.requireNonNull(other);
 379 
 380         // nothing to do
 381         if (other == this || !this.isNamed())
 382             return;
 383 
 384         // check if we already read this module
 385         Set<Module> reads = this.reads;
 386         if (reads != null && reads.contains(other))
 387             return;
 388 
 389         // update VM first, just in case it fails
 390         if (syncVM) {
 391             if (other == ALL_UNNAMED_MODULE) {
 392                 addReads0(this, null);
 393             } else {
 394                 addReads0(this, other);
 395             }
 396         }
 397 
 398         // add reflective read
 399         reflectivelyReads.putIfAbsent(this, other, Boolean.TRUE);
 400     }
 401 
 402 
 403     // -- exported and open packages --
 404 
 405     // the packages are open to other modules, can be null
 406     // if the value contains EVERYONE_MODULE then the package is open to all
 407     private volatile Map<String, Set<Module>> openPackages;
 408 
 409     // the packages that are exported, can be null
 410     // if the value contains EVERYONE_MODULE then the package is exported to all
 411     private volatile Map<String, Set<Module>> exportedPackages;
 412 
 413     // additional exports or opens added at run-time
 414     // this module (1st key), other module (2nd key)
 415     // (package name, open?) (value)
 416     private static final WeakPairMap<Module, Module, Map<String, Boolean>>
 417         reflectivelyExports = new WeakPairMap<>();
 418 
 419 
 420     /**
 421      * Returns {@code true} if this module exports the given package to at
 422      * least the given module.
 423      *
 424      * <p> This method returns {@code true} if invoked to test if a package in
 425      * this module is exported to itself. It always returns {@code true} when
 426      * invoked on an unnamed module. A package that is {@link #isOpen open} to
 427      * the given module is considered exported to that module at run-time and
 428      * so this method returns {@code true} if the package is open to the given
 429      * module. </p>
 430      *
 431      * <p> This method does not check if the given module reads this module. </p>
 432      *
 433      * @param  pn
 434      *         The package name
 435      * @param  other
 436      *         The other module
 437      *
 438      * @return {@code true} if this module exports the package to at least the
 439      *         given module
 440      *
 441      * @see ModuleDescriptor#exports()
 442      * @see #addExports(String,Module)
 443      */
 444     public boolean isExported(String pn, Module other) {
 445         Objects.requireNonNull(pn);
 446         Objects.requireNonNull(other);
 447         return implIsExportedOrOpen(pn, other, /*open*/false);
 448     }
 449 
 450     /**
 451      * Returns {@code true} if this module has <em>opened</em> a package to at
 452      * least the given module.
 453      *
 454      * <p> This method returns {@code true} if invoked to test if a package in
 455      * this module is open to itself. It returns {@code true} when invoked on an
 456      * {@link ModuleDescriptor#isOpen open} module with a package in the module.
 457      * It always returns {@code true} when invoked on an unnamed module. </p>
 458      *
 459      * <p> This method does not check if the given module reads this module. </p>
 460      *
 461      * @param  pn
 462      *         The package name
 463      * @param  other
 464      *         The other module
 465      *
 466      * @return {@code true} if this module has <em>opened</em> the package
 467      *         to at least the given module
 468      *
 469      * @see ModuleDescriptor#opens()
 470      * @see #addOpens(String,Module)
 471      * @see AccessibleObject#setAccessible(boolean)
 472      * @see java.lang.invoke.MethodHandles#privateLookupIn
 473      */
 474     public boolean isOpen(String pn, Module other) {
 475         Objects.requireNonNull(pn);
 476         Objects.requireNonNull(other);
 477         return implIsExportedOrOpen(pn, other, /*open*/true);
 478     }
 479 
 480     /**
 481      * Returns {@code true} if this module exports the given package
 482      * unconditionally.
 483      *
 484      * <p> This method always returns {@code true} when invoked on an unnamed
 485      * module. A package that is {@link #isOpen(String) opened} unconditionally
 486      * is considered exported unconditionally at run-time and so this method
 487      * returns {@code true} if the package is opened unconditionally. </p>
 488      *
 489      * <p> This method does not check if the given module reads this module. </p>
 490      *
 491      * @param  pn
 492      *         The package name
 493      *
 494      * @return {@code true} if this module exports the package unconditionally
 495      *
 496      * @see ModuleDescriptor#exports()
 497      */
 498     public boolean isExported(String pn) {
 499         Objects.requireNonNull(pn);
 500         return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/false);
 501     }
 502 
 503     /**
 504      * Returns {@code true} if this module has <em>opened</em> a package
 505      * unconditionally.
 506      *
 507      * <p> This method always returns {@code true} when invoked on an unnamed
 508      * module. Additionally, it always returns {@code true} when invoked on an
 509      * {@link ModuleDescriptor#isOpen open} module with a package in the
 510      * module. </p>
 511      *
 512      * <p> This method does not check if the given module reads this module. </p>
 513      *
 514      * @param  pn
 515      *         The package name
 516      *
 517      * @return {@code true} if this module has <em>opened</em> the package
 518      *         unconditionally
 519      *
 520      * @see ModuleDescriptor#opens()
 521      */
 522     public boolean isOpen(String pn) {
 523         Objects.requireNonNull(pn);
 524         return implIsExportedOrOpen(pn, EVERYONE_MODULE, /*open*/true);
 525     }
 526 
 527 
 528     /**
 529      * Returns {@code true} if this module exports or opens the given package
 530      * to the given module. If the other module is {@code EVERYONE_MODULE} then
 531      * this method tests if the package is exported or opened unconditionally.
 532      */
 533     private boolean implIsExportedOrOpen(String pn, Module other, boolean open) {
 534         // all packages in unnamed modules are open
 535         if (!isNamed())
 536             return true;
 537 
 538         // all packages are exported/open to self
 539         if (other == this && containsPackage(pn))
 540             return true;
 541 
 542         // all packages in open modules are open
 543         if (descriptor.isOpen())
 544             return containsPackage(pn);
 545 
 546         // exported/opened via module declaration/descriptor
 547         if (isStaticallyExportedOrOpen(pn, other, open))
 548             return true;
 549 
 550         // exported via addExports/addOpens
 551         if (isReflectivelyExportedOrOpen(pn, other, open))
 552             return true;
 553 
 554         // not exported or open to other
 555         return false;
 556     }
 557 
 558     /**
 559      * Returns {@code true} if this module exports or opens a package to
 560      * the given module via its module declaration.
 561      */
 562     boolean isStaticallyExportedOrOpen(String pn, Module other, boolean open) {
 563         // package is open to everyone or <other>
 564         Map<String, Set<Module>> openPackages = this.openPackages;
 565         if (openPackages != null) {
 566             Set<Module> targets = openPackages.get(pn);
 567             if (targets != null) {
 568                 if (targets.contains(EVERYONE_MODULE))
 569                     return true;
 570                 if (other != EVERYONE_MODULE && targets.contains(other))
 571                     return true;
 572             }
 573         }
 574 
 575         if (!open) {
 576             // package is exported to everyone or <other>
 577             Map<String, Set<Module>> exportedPackages = this.exportedPackages;
 578             if (exportedPackages != null) {
 579                 Set<Module> targets = exportedPackages.get(pn);
 580                 if (targets != null) {
 581                     if (targets.contains(EVERYONE_MODULE))
 582                         return true;
 583                     if (other != EVERYONE_MODULE && targets.contains(other))
 584                         return true;
 585                 }
 586             }
 587         }
 588 
 589         return false;
 590     }
 591 
 592 
 593     /**
 594      * Returns {@code true} if this module reflectively exports or opens given
 595      * package package to the given module.
 596      */
 597     private boolean isReflectivelyExportedOrOpen(String pn, Module other, boolean open) {
 598         // exported or open to all modules
 599         Map<String, Boolean> exports = reflectivelyExports.get(this, EVERYONE_MODULE);
 600         if (exports != null) {
 601             Boolean b = exports.get(pn);
 602             if (b != null) {
 603                 boolean isOpen = b.booleanValue();
 604                 if (!open || isOpen) return true;
 605             }
 606         }
 607 
 608         if (other != EVERYONE_MODULE) {
 609 
 610             // exported or open to other
 611             exports = reflectivelyExports.get(this, other);
 612             if (exports != null) {
 613                 Boolean b = exports.get(pn);
 614                 if (b != null) {
 615                     boolean isOpen = b.booleanValue();
 616                     if (!open || isOpen) return true;
 617                 }
 618             }
 619 
 620             // other is an unnamed module && exported or open to all unnamed
 621             if (!other.isNamed()) {
 622                 exports = reflectivelyExports.get(this, ALL_UNNAMED_MODULE);
 623                 if (exports != null) {
 624                     Boolean b = exports.get(pn);
 625                     if (b != null) {
 626                         boolean isOpen = b.booleanValue();
 627                         if (!open || isOpen) return true;
 628                     }
 629                 }
 630             }
 631 
 632         }
 633 
 634         return false;
 635     }
 636 
 637 
 638     /**
 639      * If the caller's module is this module then update this module to export
 640      * the given package to the given module.
 641      *
 642      * <p> This method has no effect if the package is already exported (or
 643      * <em>open</em>) to the given module. It also has no effect if
 644      * invoked on an {@link ModuleDescriptor#isOpen open} module. </p>
 645      *
 646      * @apiNote As specified in section 5.4.3 of the <cite>The Java&trade;
 647      * Virtual Machine Specification </cite>, if an attempt to resolve a
 648      * symbolic reference fails because of a linkage error, then subsequent
 649      * attempts to resolve the reference always fail with the same error that
 650      * was thrown as a result of the initial resolution attempt.
 651      *
 652      * @param  pn
 653      *         The package name
 654      * @param  other
 655      *         The module
 656      *
 657      * @return this module
 658      *
 659      * @throws IllegalArgumentException
 660      *         If {@code pn} is {@code null}, or this is a named module and the
 661      *         package {@code pn} is not a package in this module
 662      * @throws IllegalStateException
 663      *         If this is a named module and the caller is not this module
 664      *
 665      * @jvms 5.4.3 Resolution
 666      * @see #isExported(String,Module)
 667      */
 668     @CallerSensitive
 669     public Module addExports(String pn, Module other) {
 670         if (pn == null)
 671             throw new IllegalArgumentException("package is null");
 672         Objects.requireNonNull(other);
 673 
 674         if (isNamed() && !descriptor.isOpen()) {
 675             Module caller = Reflection.getCallerClass().getModule();
 676             if (caller != this) {
 677                 throw new IllegalStateException(caller + " != " + this);
 678             }
 679             implAddExportsOrOpens(pn, other, /*open*/false, /*syncVM*/true);
 680         }
 681 
 682         return this;
 683     }
 684 
 685     /**
 686      * If this module has <em>opened</em> a package to at least the caller
 687      * module then update this module to open the package to the given module.
 688      * Opening a package with this method allows all types in the package,
 689      * and all their members, not just public types and their public members,
 690      * to be reflected on by the given module when using APIs that support
 691      * private access or a way to bypass or suppress default Java language
 692      * access control checks.
 693      *
 694      * <p> This method has no effect if the package is already <em>open</em>
 695      * to the given module. It also has no effect if invoked on an {@link
 696      * ModuleDescriptor#isOpen open} module. </p>
 697      *
 698      * @param  pn
 699      *         The package name
 700      * @param  other
 701      *         The module
 702      *
 703      * @return this module
 704      *
 705      * @throws IllegalArgumentException
 706      *         If {@code pn} is {@code null}, or this is a named module and the
 707      *         package {@code pn} is not a package in this module
 708      * @throws IllegalStateException
 709      *         If this is a named module and this module has not opened the
 710      *         package to at least the caller
 711      *
 712      * @see #isOpen(String,Module)
 713      * @see AccessibleObject#setAccessible(boolean)
 714      * @see java.lang.invoke.MethodHandles#privateLookupIn
 715      */
 716     @CallerSensitive
 717     public Module addOpens(String pn, Module other) {
 718         if (pn == null)
 719             throw new IllegalArgumentException("package is null");
 720         Objects.requireNonNull(other);
 721 
 722         if (isNamed() && !descriptor.isOpen()) {
 723             Module caller = Reflection.getCallerClass().getModule();
 724             if (caller != this && !isOpen(pn, caller))
 725                 throw new IllegalStateException(pn + " is not open to " + caller);
 726             implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
 727         }
 728 
 729         return this;
 730     }
 731 
 732 
 733     /**
 734      * Updates the exports so that package {@code pn} is exported to module
 735      * {@code other} but without notifying the VM.
 736      *
 737      * @apiNote This method is for VM white-box testing.
 738      */
 739     void implAddExportsNoSync(String pn, Module other) {
 740         if (other == null)
 741             other = EVERYONE_MODULE;
 742         implAddExportsOrOpens(pn.replace('/', '.'), other, false, false);
 743     }
 744 
 745     /**
 746      * Updates the exports so that package {@code pn} is exported to module
 747      * {@code other}.
 748      *
 749      * @apiNote This method is for white-box testing.
 750      */
 751     void implAddExports(String pn, Module other) {
 752         implAddExportsOrOpens(pn, other, false, true);
 753     }
 754 
 755     /**
 756      * Updates the module to open package {@code pn} to module {@code other}.
 757      *
 758      * @apiNote This method is for white-box tests and jtreg
 759      */
 760     void implAddOpens(String pn, Module other) {
 761         implAddExportsOrOpens(pn, other, true, true);
 762     }
 763 
 764     /**
 765      * Updates a module to export or open a module to another module.
 766      *
 767      * If {@code syncVM} is {@code true} then the VM is notified.
 768      */
 769     private void implAddExportsOrOpens(String pn,
 770                                        Module other,
 771                                        boolean open,
 772                                        boolean syncVM) {
 773         Objects.requireNonNull(other);
 774         Objects.requireNonNull(pn);
 775 
 776         // all packages are open in unnamed and open modules
 777         if (!isNamed() || descriptor.isOpen())
 778             return;
 779 
 780         // nothing to do if already exported/open to other
 781         if (implIsExportedOrOpen(pn, other, open))
 782             return;
 783 
 784         // can only export a package in the module
 785         if (!containsPackage(pn)) {
 786             throw new IllegalArgumentException("package " + pn
 787                                                + " not in contents");
 788         }
 789 
 790         // update VM first, just in case it fails
 791         if (syncVM) {
 792             String pkgInternalForm = pn.replace('.', '/');
 793             if (other == EVERYONE_MODULE) {
 794                 addExportsToAll0(this, pkgInternalForm);
 795             } else if (other == ALL_UNNAMED_MODULE) {
 796                 addExportsToAllUnnamed0(this, pkgInternalForm);
 797             } else {
 798                 addExports0(this, pkgInternalForm, other);
 799             }
 800         }
 801 
 802         // add package name to reflectivelyExports if absent
 803         Map<String, Boolean> map = reflectivelyExports
 804             .computeIfAbsent(this, other,
 805                              (m1, m2) -> new ConcurrentHashMap<>());
 806 
 807         if (open) {
 808             map.put(pn, Boolean.TRUE);  // may need to promote from FALSE to TRUE
 809         } else {
 810             map.putIfAbsent(pn, Boolean.FALSE);
 811         }
 812     }
 813 
 814 
 815     // -- services --
 816 
 817     // additional service type (2nd key) that some module (1st key) uses
 818     private static final WeakPairMap<Module, Class<?>, Boolean> reflectivelyUses
 819         = new WeakPairMap<>();
 820 
 821     /**
 822      * If the caller's module is this module then update this module to add a
 823      * service dependence on the given service type. This method is intended
 824      * for use by frameworks that invoke {@link java.util.ServiceLoader
 825      * ServiceLoader} on behalf of other modules or where the framework is
 826      * passed a reference to the service type by other code. This method is
 827      * a no-op when invoked on an unnamed module or an automatic module.
 828      *
 829      * <p> This method does not cause {@link
 830      * Configuration#resolveRequiresAndUses resolveRequiresAndUses} to be
 831      * re-run. </p>
 832      *
 833      * @param  service
 834      *         The service type
 835      *
 836      * @return this module
 837      *
 838      * @throws IllegalStateException
 839      *         If this is a named module and the caller is not this module
 840      *
 841      * @see #canUse(Class)
 842      * @see ModuleDescriptor#uses()
 843      */
 844     @CallerSensitive
 845     public Module addUses(Class<?> service) {
 846         Objects.requireNonNull(service);
 847 
 848         if (isNamed() && !descriptor.isAutomatic()) {
 849             Module caller = Reflection.getCallerClass().getModule();
 850             if (caller != this) {
 851                 throw new IllegalStateException(caller + " != " + this);
 852             }
 853             implAddUses(service);
 854         }
 855 
 856         return this;
 857     }
 858 
 859     /**
 860      * Update this module to add a service dependence on the given service
 861      * type.
 862      */
 863     void implAddUses(Class<?> service) {
 864         if (!canUse(service)) {
 865             reflectivelyUses.putIfAbsent(this, service, Boolean.TRUE);
 866         }
 867     }
 868 
 869 
 870     /**
 871      * Indicates if this module has a service dependence on the given service
 872      * type. This method always returns {@code true} when invoked on an unnamed
 873      * module or an automatic module.
 874      *
 875      * @param  service
 876      *         The service type
 877      *
 878      * @return {@code true} if this module uses service type {@code st}
 879      *
 880      * @see #addUses(Class)
 881      */
 882     public boolean canUse(Class<?> service) {
 883         Objects.requireNonNull(service);
 884 
 885         if (!isNamed())
 886             return true;
 887 
 888         if (descriptor.isAutomatic())
 889             return true;
 890 
 891         // uses was declared
 892         if (descriptor.uses().contains(service.getName()))
 893             return true;
 894 
 895         // uses added via addUses
 896         return reflectivelyUses.containsKeyPair(this, service);
 897     }
 898 
 899 
 900 
 901     // -- packages --
 902 
 903     // Additional packages that are added to the module at run-time.
 904     // The field is volatile as it may be replaced at run-time
 905     private volatile Set<String> extraPackages;
 906 
 907     private boolean containsPackage(String pn) {
 908         if (descriptor.packages().contains(pn))
 909             return true;
 910         Set<String> extraPackages = this.extraPackages;
 911         if (extraPackages != null && extraPackages.contains(pn))
 912             return true;
 913         return false;
 914     }
 915 
 916 
 917     /**
 918      * Returns an array of the package names of the packages in this module.
 919      *
 920      * <p> For named modules, the returned array contains an element for each
 921      * package in the module. It may contain elements corresponding to packages
 922      * added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a>
 923      * for example, after it was loaded.
 924      *
 925      * <p> For unnamed modules, this method is the equivalent of invoking the
 926      * {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
 927      * this module's class loader and returning the array of package names. </p>
 928      *
 929      * <p> A package name appears at most once in the returned array. </p>
 930      *
 931      * @apiNote This method returns an array rather than a {@code Set} for
 932      * consistency with other {@code java.lang.reflect} types.
 933      *
 934      * @return an array of the package names of the packages in this module
 935      */
 936     public String[] getPackages() {
 937         if (isNamed()) {
 938 
 939             Set<String> packages = descriptor.packages();
 940             Set<String> extraPackages = this.extraPackages;
 941             if (extraPackages == null) {
 942                 return packages.toArray(new String[0]);
 943             } else {
 944                 return Stream.concat(packages.stream(),
 945                                      extraPackages.stream())
 946                         .toArray(String[]::new);
 947             }
 948 
 949         } else {
 950             // unnamed module
 951             Stream<Package> packages;
 952             if (loader == null) {
 953                 packages = BootLoader.packages();
 954             } else {
 955                 packages = SharedSecrets.getJavaLangAccess().packages(loader);
 956             }
 957             return packages.map(Package::getName).toArray(String[]::new);
 958         }
 959     }
 960 
 961     /**
 962      * Add a package to this module.
 963      *
 964      * @apiNote This method is for Proxy use.
 965      *
 966      * @apiNote This is an expensive operation, not expected to be used often.
 967      * At this time then it does not validate that the package name is a
 968      * valid java identifier.
 969      */
 970     void addPackage(String pn) {
 971         implAddPackage(pn, true);
 972     }
 973 
 974     /**
 975      * Add a package to this module without notifying the VM.
 976      *
 977      * @apiNote This method is VM white-box testing.
 978      */
 979     void implAddPackageNoSync(String pn) {
 980         implAddPackage(pn.replace('/', '.'), false);
 981     }
 982 
 983     /**
 984      * Add a package to this module.
 985      *
 986      * If {@code syncVM} is {@code true} then the VM is notified.
 987      */
 988     private void implAddPackage(String pn, boolean syncVM) {
 989         if (!isNamed())
 990             throw new InternalError("adding package to unnamed module?");
 991         if (descriptor.isOpen())
 992             throw new InternalError("adding package to open module?");
 993         if (pn.isEmpty())
 994             throw new InternalError("adding <unnamed> package to module?");
 995 
 996         if (descriptor.packages().contains(pn)) {
 997             // already in module
 998             return;
 999         }
1000 
1001         Set<String> extraPackages = this.extraPackages;
1002         if (extraPackages != null && extraPackages.contains(pn)) {
1003             // already added
1004             return;
1005         }
1006         synchronized (this) {
1007             // recheck under lock
1008             extraPackages = this.extraPackages;
1009             if (extraPackages != null) {
1010                 if (extraPackages.contains(pn)) {
1011                     // already added
1012                     return;
1013                 }
1014 
1015                 // copy the set
1016                 extraPackages = new HashSet<>(extraPackages);
1017                 extraPackages.add(pn);
1018             } else {
1019                 extraPackages = Collections.singleton(pn);
1020             }
1021 
1022             // update VM first, just in case it fails
1023             if (syncVM)
1024                 addPackage0(this, pn.replace('.', '/'));
1025 
1026             // replace with new set
1027             this.extraPackages = extraPackages; // volatile write
1028         }
1029     }
1030 
1031 
1032     // -- creating Module objects --
1033 
1034     /**
1035      * Defines all module in a configuration to the runtime.
1036      *
1037      * @return a map of module name to runtime {@code Module}
1038      *
1039      * @throws IllegalArgumentException
1040      *         If defining any of the modules to the VM fails
1041      */
1042     static Map<String, Module> defineModules(Configuration cf,
1043                                              Function<String, ClassLoader> clf,
1044                                              Layer layer)
1045     {
1046         Map<String, Module> nameToModule = new HashMap<>();
1047         Map<String, ClassLoader> moduleToLoader = new HashMap<>();
1048 
1049         boolean isBootLayer = (Layer.boot() == null);
1050         Set<ClassLoader> loaders = new HashSet<>();
1051 
1052         // map each module to a class loader
1053         for (ResolvedModule resolvedModule : cf.modules()) {
1054             String name = resolvedModule.name();
1055             ClassLoader loader = clf.apply(name);
1056             if (loader != null) {
1057                 moduleToLoader.put(name, loader);
1058                 loaders.add(loader);
1059             } else if (!isBootLayer) {
1060                 throw new IllegalArgumentException("loader can't be 'null'");
1061             }
1062         }
1063 
1064         // define each module in the configuration to the VM
1065         for (ResolvedModule resolvedModule : cf.modules()) {
1066             ModuleReference mref = resolvedModule.reference();
1067             ModuleDescriptor descriptor = mref.descriptor();
1068             String name = descriptor.name();
1069             URI uri = mref.location().orElse(null);
1070             ClassLoader loader = moduleToLoader.get(resolvedModule.name());
1071             Module m;
1072             if (loader == null && isBootLayer && name.equals("java.base")) {
1073                 // java.base is already defined to the VM
1074                 m = Object.class.getModule();
1075             } else {
1076                 m = new Module(layer, loader, descriptor, uri);
1077             }
1078             nameToModule.put(name, m);
1079             moduleToLoader.put(name, loader);
1080         }
1081 
1082         // setup readability and exports
1083         for (ResolvedModule resolvedModule : cf.modules()) {
1084             ModuleReference mref = resolvedModule.reference();
1085             ModuleDescriptor descriptor = mref.descriptor();
1086 
1087             String mn = descriptor.name();
1088             Module m = nameToModule.get(mn);
1089             assert m != null;
1090 
1091             // reads
1092             Set<Module> reads = new HashSet<>();
1093             for (ResolvedModule other : resolvedModule.reads()) {
1094                 Module m2 = null;
1095                 if (other.configuration() == cf) {
1096                     String dn = other.reference().descriptor().name();
1097                     m2 = nameToModule.get(dn);
1098                 } else {
1099                     for (Layer parent: layer.parents()) {
1100                         m2 = findModule(parent, other);
1101                         if (m2 != null)
1102                             break;
1103                     }
1104                 }
1105                 assert m2 != null;
1106 
1107                 reads.add(m2);
1108 
1109                 // update VM view
1110                 addReads0(m, m2);
1111             }
1112             m.reads = reads;
1113 
1114             // automatic modules read all unnamed modules
1115             if (descriptor.isAutomatic()) {
1116                 m.implAddReads(ALL_UNNAMED_MODULE, true);
1117             }
1118 
1119             // exports and opens
1120             initExportsAndOpens(descriptor, nameToModule, m);
1121         }
1122 
1123         // register the modules in the boot layer
1124         if (isBootLayer) {
1125             for (ResolvedModule resolvedModule : cf.modules()) {
1126                 ModuleReference mref = resolvedModule.reference();
1127                 ModuleDescriptor descriptor = mref.descriptor();
1128                 if (!descriptor.provides().isEmpty()) {
1129                     String name = descriptor.name();
1130                     Module m = nameToModule.get(name);
1131                     ClassLoader loader = moduleToLoader.get(name);
1132                     ServicesCatalog catalog;
1133                     if (loader == null) {
1134                         catalog = BootLoader.getServicesCatalog();
1135                     } else {
1136                         catalog = ServicesCatalog.getServicesCatalog(loader);
1137                     }
1138                     catalog.register(m);
1139                 }
1140             }
1141         }
1142 
1143         // record that there is a layer with modules defined to the class loader
1144         for (ClassLoader loader : loaders) {
1145             layer.bindToLoader(loader);
1146         }
1147 
1148         return nameToModule;
1149     }
1150 
1151 
1152     /**
1153      * Find the runtime Module corresponding to the given ResolvedModule
1154      * in the given parent layer (or its parents).
1155      */
1156     private static Module findModule(Layer parent, ResolvedModule resolvedModule) {
1157         Configuration cf = resolvedModule.configuration();
1158         String dn = resolvedModule.name();
1159         return parent.layers()
1160                 .filter(l -> l.configuration() == cf)
1161                 .findAny()
1162                 .map(layer -> {
1163                     Optional<Module> om = layer.findModule(dn);
1164                     assert om.isPresent() : dn + " not found in layer";
1165                     Module m = om.get();
1166                     assert m.getLayer() == layer : m + " not in expected layer";
1167                     return m;
1168                 })
1169                 .orElse(null);
1170     }
1171 
1172     /**
1173      * Initialize the maps of exported and open packages for module m.
1174      */
1175     private static void initExportsAndOpens(ModuleDescriptor descriptor,
1176                                             Map<String, Module> nameToModule,
1177                                             Module m)
1178     {
1179         // The VM doesn't know about open modules so need to export all packages
1180         if (descriptor.isOpen()) {
1181             assert descriptor.opens().isEmpty();
1182             for (String source : descriptor.packages()) {
1183                 String sourceInternalForm = source.replace('.', '/');
1184                 addExportsToAll0(m, sourceInternalForm);
1185             }
1186             return;
1187         }
1188 
1189         Map<String, Set<Module>> openPackages = new HashMap<>();
1190         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1191 
1192         // process the open packages first
1193         for (Opens opens : descriptor.opens()) {
1194             String source = opens.source();
1195             String sourceInternalForm = source.replace('.', '/');
1196 
1197             if (opens.isQualified()) {
1198                 // qualified opens
1199                 Set<Module> targets = new HashSet<>();
1200                 for (String target : opens.targets()) {
1201                     // only open to modules that are in this configuration
1202                     Module m2 = nameToModule.get(target);
1203                     if (m2 != null) {
1204                         addExports0(m, sourceInternalForm, m2);
1205                         targets.add(m2);
1206                     }
1207                 }
1208                 if (!targets.isEmpty()) {
1209                     openPackages.put(source, targets);
1210                 }
1211             } else {
1212                 // unqualified opens
1213                 addExportsToAll0(m, sourceInternalForm);
1214                 openPackages.put(source, EVERYONE_SET);
1215             }
1216         }
1217 
1218         // next the exports, skipping exports when the package is open
1219         for (Exports exports : descriptor.exports()) {
1220             String source = exports.source();
1221             String sourceInternalForm = source.replace('.', '/');
1222 
1223             // skip export if package is already open to everyone
1224             Set<Module> openToTargets = openPackages.get(source);
1225             if (openToTargets != null && openToTargets.contains(EVERYONE_MODULE))
1226                 continue;
1227 
1228             if (exports.isQualified()) {
1229                 // qualified exports
1230                 Set<Module> targets = new HashSet<>();
1231                 for (String target : exports.targets()) {
1232                     // only export to modules that are in this configuration
1233                     Module m2 = nameToModule.get(target);
1234                     if (m2 != null) {
1235                         // skip qualified export if already open to m2
1236                         if (openToTargets == null || !openToTargets.contains(m2)) {
1237                             addExports0(m, sourceInternalForm, m2);
1238                             targets.add(m2);
1239                         }
1240                     }
1241                 }
1242                 if (!targets.isEmpty()) {
1243                     exportedPackages.put(source, targets);
1244                 }
1245 
1246             } else {
1247                 // unqualified exports
1248                 addExportsToAll0(m, sourceInternalForm);
1249                 exportedPackages.put(source, EVERYONE_SET);
1250             }
1251         }
1252 
1253         if (!openPackages.isEmpty())
1254             m.openPackages = openPackages;
1255         if (!exportedPackages.isEmpty())
1256             m.exportedPackages = exportedPackages;
1257     }
1258 
1259 
1260     // -- annotations --
1261 
1262     /**
1263      * {@inheritDoc}
1264      * This method returns {@code null} when invoked on an unnamed module.
1265      */
1266     @Override
1267     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1268         return moduleInfoClass().getDeclaredAnnotation(annotationClass);
1269     }
1270 
1271     /**
1272      * {@inheritDoc}
1273      * This method returns an empty array when invoked on an unnamed module.
1274      */
1275     @Override
1276     public Annotation[] getAnnotations() {
1277         return moduleInfoClass().getAnnotations();
1278     }
1279 
1280     /**
1281      * {@inheritDoc}
1282      * This method returns an empty array when invoked on an unnamed module.
1283      */
1284     @Override
1285     public Annotation[] getDeclaredAnnotations() {
1286         return moduleInfoClass().getDeclaredAnnotations();
1287     }
1288 
1289     // cached class file with annotations
1290     private volatile Class<?> moduleInfoClass;
1291 
1292     private Class<?> moduleInfoClass() {
1293         Class<?> clazz = this.moduleInfoClass;
1294         if (clazz != null)
1295             return clazz;
1296 
1297         synchronized (this) {
1298             clazz = this.moduleInfoClass;
1299             if (clazz == null) {
1300                 if (isNamed()) {
1301                     PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass;
1302                     clazz = AccessController.doPrivileged(pa);
1303                 }
1304                 if (clazz == null) {
1305                     class DummyModuleInfo { }
1306                     clazz = DummyModuleInfo.class;
1307                 }
1308                 this.moduleInfoClass = clazz;
1309             }
1310             return clazz;
1311         }
1312     }
1313 
1314     private Class<?> loadModuleInfoClass() {
1315         Class<?> clazz = null;
1316         try (InputStream in = getResourceAsStream("module-info.class")) {
1317             if (in != null)
1318                 clazz = loadModuleInfoClass(in);
1319         } catch (Exception ignore) { }
1320         return clazz;
1321     }
1322 
1323     /**
1324      * Loads module-info.class as a package-private interface in a class loader
1325      * that is a child of this module's class loader.
1326      */
1327     private Class<?> loadModuleInfoClass(InputStream in) throws IOException {
1328         final String MODULE_INFO = "module-info";
1329 
1330         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
1331                                          + ClassWriter.COMPUTE_FRAMES);
1332 
1333         ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
1334             @Override
1335             public void visit(int version,
1336                               int access,
1337                               String name,
1338                               String signature,
1339                               String superName,
1340                               String[] interfaces) {
1341                 cw.visit(version,
1342                         Opcodes.ACC_INTERFACE
1343                             + Opcodes.ACC_ABSTRACT
1344                             + Opcodes.ACC_SYNTHETIC,
1345                         MODULE_INFO,
1346                         null,
1347                         "java/lang/Object",
1348                         null);
1349             }
1350             @Override
1351             public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
1352                 // keep annotations
1353                 return super.visitAnnotation(desc, visible);
1354             }
1355             @Override
1356             public void visitAttribute(Attribute attr) {
1357                 // drop non-annotation attributes
1358             }
1359         };
1360 
1361         ClassReader cr = new ClassReader(in);
1362         cr.accept(cv, 0);
1363         byte[] bytes = cw.toByteArray();
1364 
1365         ClassLoader cl = new ClassLoader(loader) {
1366             @Override
1367             protected Class<?> findClass(String cn)throws ClassNotFoundException {
1368                 if (cn.equals(MODULE_INFO)) {
1369                     return super.defineClass(cn, bytes, 0, bytes.length);
1370                 } else {
1371                     throw new ClassNotFoundException(cn);
1372                 }
1373             }
1374         };
1375 
1376         try {
1377             return cl.loadClass(MODULE_INFO);
1378         } catch (ClassNotFoundException e) {
1379             throw new InternalError(e);
1380         }
1381     }
1382 
1383 
1384     // -- misc --
1385 
1386 
1387     /**
1388      * Returns an input stream for reading a resource in this module. The
1389      * {@code name} parameter is a {@code '/'}-separated path name that
1390      * identifies the resource.
1391      *
1392      * <p> A resource in a named modules may be <em>encapsulated</em> so that
1393      * it cannot be located by code in other modules. Whether a resource can be
1394      * located or not is determined as follows:
1395      *
1396      * <ul>
1397      *     <li> The <em>package name</em> of the resource is derived from the
1398      *     subsequence of characters that precedes the last {@code '/'} and then
1399      *     replacing each {@code '/'} character in the subsequence with
1400      *     {@code '.'}. For example, the package name derived for a resource
1401      *     named "{@code a/b/c/foo.properties}" is "{@code a.b.c}". </li>
1402      *
1403      *     <li> If the package name is a package in the module then the package
1404      *     must be {@link #isOpen open} the module of the caller of this method.
1405      *     If the package is not in the module then the resource is not
1406      *     encapsulated. Resources in the unnamed package or "{@code META-INF}",
1407      *     for example, are never encapsulated because they can never be
1408      *     packages in a named module. </li>
1409      *
1410      *     <li> As a special case, resources ending with "{@code .class}" are
1411      *     never encapsulated. </li>
1412      * </ul>
1413      *
1414      * <p> This method returns {@code null} if the resource is not in this
1415      * module, the resource is encapsulated and cannot be located by the caller,
1416      * or access to the resource is denied by the security manager.
1417      *
1418      * @param  name
1419      *         The resource name
1420      *
1421      * @return An input stream for reading the resource or {@code null}
1422      *
1423      * @throws IOException
1424      *         If an I/O error occurs
1425      *
1426      * @see java.lang.module.ModuleReader#open(String)
1427      */
1428     @CallerSensitive
1429     public InputStream getResourceAsStream(String name) throws IOException {
1430         Objects.requireNonNull(name);
1431 
1432         if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
1433             Module caller = Reflection.getCallerClass().getModule();
1434             if (caller != this && caller != Object.class.getModule()) {
1435                 // ignore packages added for proxies via addPackage
1436                 Set<String> packages = getDescriptor().packages();
1437                 String pn = ResourceHelper.getPackageName(name);
1438                 if (packages.contains(pn) && !isOpen(pn, caller)) {
1439                     // resource is in package not open to caller
1440                     return null;
1441                 }
1442             }
1443         }
1444 
1445         String mn = this.name;
1446 
1447         // special-case built-in class loaders to avoid URL connection
1448         if (loader == null) {
1449             return BootLoader.findResourceAsStream(mn, name);
1450         } else if (loader instanceof BuiltinClassLoader) {
1451             return ((BuiltinClassLoader) loader).findResourceAsStream(mn, name);
1452         }
1453 
1454         // locate resource in module
1455         JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
1456         URL url = jla.findResource(loader, mn, name);
1457         if (url != null) {
1458             try {
1459                 return url.openStream();
1460             } catch (SecurityException e) { }
1461         }
1462 
1463         return null;
1464     }
1465 
1466     /**
1467      * Returns the string representation of this module. For a named module,
1468      * the representation is the string {@code "module"}, followed by a space,
1469      * and then the module name. For an unnamed module, the representation is
1470      * the string {@code "unnamed module"}, followed by a space, and then an
1471      * implementation specific string that identifies the unnamed module.
1472      *
1473      * @return The string representation of this module
1474      */
1475     @Override
1476     public String toString() {
1477         if (isNamed()) {
1478             return "module " + name;
1479         } else {
1480             String id = Integer.toHexString(System.identityHashCode(this));
1481             return "unnamed module @" + id;
1482         }
1483     }
1484 
1485 
1486     // -- native methods --
1487 
1488     // JVM_DefineModule
1489     private static native void defineModule0(Module module,
1490                                              boolean isOpen,
1491                                              String version,
1492                                              String location,
1493                                              String[] pns);
1494 
1495     // JVM_AddReadsModule
1496     private static native void addReads0(Module from, Module to);
1497 
1498     // JVM_AddModuleExports
1499     private static native void addExports0(Module from, String pn, Module to);
1500 
1501     // JVM_AddModuleExportsToAll
1502     private static native void addExportsToAll0(Module from, String pn);
1503 
1504     // JVM_AddModuleExportsToAllUnnamed
1505     private static native void addExportsToAllUnnamed0(Module from, String pn);
1506 
1507     // JVM_AddModulePackage
1508     private static native void addPackage0(Module m, String pn);
1509 
1510     /**
1511      * Register shared secret to provide access to package-private methods
1512      */
1513     static {
1514         SharedSecrets.setJavaLangReflectModuleAccess(
1515             new JavaLangReflectModuleAccess() {
1516                 @Override
1517                 public Module defineUnnamedModule(ClassLoader loader) {
1518                     return new Module(loader);
1519                 }
1520                 @Override
1521                 public Module defineModule(ClassLoader loader,
1522                                            ModuleDescriptor descriptor,
1523                                            URI uri) {
1524                    return new Module(null, loader, descriptor, uri);
1525                 }
1526                 @Override
1527                 public void addReads(Module m1, Module m2) {
1528                     m1.implAddReads(m2, true);
1529                 }
1530                 @Override
1531                 public void addReadsAllUnnamed(Module m) {
1532                     m.implAddReads(Module.ALL_UNNAMED_MODULE);
1533                 }
1534                 @Override
1535                 public void addExports(Module m, String pn, Module other) {
1536                     m.implAddExportsOrOpens(pn, other, false, true);
1537                 }
1538                 @Override
1539                 public void addOpens(Module m, String pn, Module other) {
1540                     m.implAddExportsOrOpens(pn, other, true, true);
1541                 }
1542                 @Override
1543                 public void addExportsToAll(Module m, String pn) {
1544                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, false, true);
1545                 }
1546                 @Override
1547                 public void addOpensToAll(Module m, String pn) {
1548                     m.implAddExportsOrOpens(pn, Module.EVERYONE_MODULE, true, true);
1549                 }
1550                 @Override
1551                 public void addExportsToAllUnnamed(Module m, String pn) {
1552                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, false, true);
1553                 }
1554                 @Override
1555                 public void addOpensToAllUnnamed(Module m, String pn) {
1556                     m.implAddExportsOrOpens(pn, Module.ALL_UNNAMED_MODULE, true, true);
1557                 }
1558                 @Override
1559                 public void addUses(Module m, Class<?> service) {
1560                     m.implAddUses(service);
1561                 }
1562                 @Override
1563                 public void addPackage(Module m, String pn) {
1564                     m.implAddPackage(pn, true);
1565                 }
1566                 @Override
1567                 public ServicesCatalog getServicesCatalog(Layer layer) {
1568                     return layer.getServicesCatalog();
1569                 }
1570                 @Override
1571                 public Stream<Layer> layers(Layer layer) {
1572                     return layer.layers();
1573                 }
1574                 @Override
1575                 public Stream<Layer> layers(ClassLoader loader) {
1576                     return Layer.layers(loader);
1577                 }
1578                 @Override
1579                 public boolean isStaticallyExported(Module module, String pn, Module other) {
1580                     return module.isStaticallyExportedOrOpen(pn, other, false);
1581                 }
1582             });
1583     }
1584 }