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