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() || descriptor.isAutomatic();
 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         }
1046         extraPackages.putIfAbsent(pn, Boolean.TRUE);
1047     }
1048 
1049 
1050     // -- creating Module objects --
1051 
1052     /**
1053      * Defines all module in a configuration to the runtime.
1054      *
1055      * @return a map of module name to runtime {@code Module}
1056      *
1057      * @throws IllegalArgumentException
1058      *         If defining any of the modules to the VM fails
1059      */
1060     static Map<String, Module> defineModules(Configuration cf,
1061                                              Function<String, ClassLoader> clf,
1062                                              ModuleLayer layer)
1063     {
1064         Map<String, Module> nameToModule = new HashMap<>();
1065         Map<String, ClassLoader> moduleToLoader = new HashMap<>();
1066 
1067         boolean isBootLayer = (ModuleLayer.boot() == null);
1068         Set<ClassLoader> loaders = new HashSet<>();
1069 
1070         // map each module to a class loader
1071         for (ResolvedModule resolvedModule : cf.modules()) {
1072             String name = resolvedModule.name();
1073             ClassLoader loader = clf.apply(name);
1074             if (loader != null) {
1075                 moduleToLoader.put(name, loader);
1076                 loaders.add(loader);
1077             } else if (!isBootLayer) {
1078                 throw new IllegalArgumentException("loader can't be 'null'");
1079             }
1080         }
1081 
1082         // define each module in the configuration to the VM
1083         for (ResolvedModule resolvedModule : cf.modules()) {
1084             ModuleReference mref = resolvedModule.reference();
1085             ModuleDescriptor descriptor = mref.descriptor();
1086             String name = descriptor.name();
1087             URI uri = mref.location().orElse(null);
1088             ClassLoader loader = moduleToLoader.get(resolvedModule.name());
1089             Module m;
1090             if (loader == null && isBootLayer && name.equals("java.base")) {
1091                 // java.base is already defined to the VM
1092                 m = Object.class.getModule();
1093             } else {
1094                 m = new Module(layer, loader, descriptor, uri);
1095             }
1096             nameToModule.put(name, m);
1097             moduleToLoader.put(name, loader);
1098         }
1099 
1100         // setup readability and exports
1101         for (ResolvedModule resolvedModule : cf.modules()) {
1102             ModuleReference mref = resolvedModule.reference();
1103             ModuleDescriptor descriptor = mref.descriptor();
1104 
1105             String mn = descriptor.name();
1106             Module m = nameToModule.get(mn);
1107             assert m != null;
1108 
1109             // reads
1110             Set<Module> reads = new HashSet<>();
1111 
1112             // name -> source Module when in parent layer
1113             Map<String, Module> nameToSource = Collections.emptyMap();
1114 
1115             for (ResolvedModule other : resolvedModule.reads()) {
1116                 Module m2 = null;
1117                 if (other.configuration() == cf) {
1118                     // this configuration
1119                     m2 = nameToModule.get(other.name());
1120                     assert m2 != null;
1121                 } else {
1122                     // parent layer
1123                     for (ModuleLayer parent: layer.parents()) {
1124                         m2 = findModule(parent, other);
1125                         if (m2 != null)
1126                             break;
1127                     }
1128                     assert m2 != null;
1129                     if (nameToSource.isEmpty())
1130                         nameToSource = new HashMap<>();
1131                     nameToSource.put(other.name(), m2);
1132                 }
1133                 reads.add(m2);
1134 
1135                 // update VM view
1136                 addReads0(m, m2);
1137             }
1138             m.reads = reads;
1139 
1140             // automatic modules read all unnamed modules
1141             if (descriptor.isAutomatic()) {
1142                 m.implAddReads(ALL_UNNAMED_MODULE, true);
1143             }
1144 
1145             // exports and opens
1146             initExportsAndOpens(m, nameToSource, nameToModule, layer.parents());
1147         }
1148 
1149         // register the modules in the boot layer
1150         if (isBootLayer) {
1151             for (ResolvedModule resolvedModule : cf.modules()) {
1152                 ModuleReference mref = resolvedModule.reference();
1153                 ModuleDescriptor descriptor = mref.descriptor();
1154                 if (!descriptor.provides().isEmpty()) {
1155                     String name = descriptor.name();
1156                     Module m = nameToModule.get(name);
1157                     ClassLoader loader = moduleToLoader.get(name);
1158                     ServicesCatalog catalog;
1159                     if (loader == null) {
1160                         catalog = BootLoader.getServicesCatalog();
1161                     } else {
1162                         catalog = ServicesCatalog.getServicesCatalog(loader);
1163                     }
1164                     catalog.register(m);
1165                 }
1166             }
1167         }
1168 
1169         // record that there is a layer with modules defined to the class loader
1170         for (ClassLoader loader : loaders) {
1171             layer.bindToLoader(loader);
1172         }
1173 
1174         return nameToModule;
1175     }
1176 
1177 
1178     /**
1179      * Find the runtime Module corresponding to the given ResolvedModule
1180      * in the given parent layer (or its parents).
1181      */
1182     private static Module findModule(ModuleLayer parent,
1183                                      ResolvedModule resolvedModule) {
1184         Configuration cf = resolvedModule.configuration();
1185         String dn = resolvedModule.name();
1186         return parent.layers()
1187                 .filter(l -> l.configuration() == cf)
1188                 .findAny()
1189                 .map(layer -> {
1190                     Optional<Module> om = layer.findModule(dn);
1191                     assert om.isPresent() : dn + " not found in layer";
1192                     Module m = om.get();
1193                     assert m.getLayer() == layer : m + " not in expected layer";
1194                     return m;
1195                 })
1196                 .orElse(null);
1197     }
1198 
1199 
1200     /**
1201      * Initialize the maps of exported and open packages for module m.
1202      */
1203     private static void initExportsAndOpens(Module m,
1204                                             Map<String, Module> nameToSource,
1205                                             Map<String, Module> nameToModule,
1206                                             List<ModuleLayer> parents) {
1207         // The VM special cases open and automatic modules so don't need to
1208         // export their packages
1209         ModuleDescriptor descriptor = m.getDescriptor();
1210         if (descriptor.isOpen() || descriptor.isAutomatic()) {
1211             return;
1212         }
1213 
1214         Map<String, Set<Module>> openPackages = new HashMap<>();
1215         Map<String, Set<Module>> exportedPackages = new HashMap<>();
1216 
1217         // process the open packages first
1218         for (Opens opens : descriptor.opens()) {
1219             String source = opens.source();
1220 
1221             if (opens.isQualified()) {
1222                 // qualified opens
1223                 Set<Module> targets = new HashSet<>();
1224                 for (String target : opens.targets()) {
1225                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1226                     if (m2 != null) {
1227                         addExports0(m, source, m2);
1228                         targets.add(m2);
1229                     }
1230                 }
1231                 if (!targets.isEmpty()) {
1232                     openPackages.put(source, targets);
1233                 }
1234             } else {
1235                 // unqualified opens
1236                 addExportsToAll0(m, source);
1237                 openPackages.put(source, EVERYONE_SET);
1238             }
1239         }
1240 
1241         // next the exports, skipping exports when the package is open
1242         for (Exports exports : descriptor.exports()) {
1243             String source = exports.source();
1244 
1245             // skip export if package is already open to everyone
1246             Set<Module> openToTargets = openPackages.get(source);
1247             if (openToTargets != null && openToTargets.contains(EVERYONE_MODULE))
1248                 continue;
1249 
1250             if (exports.isQualified()) {
1251                 // qualified exports
1252                 Set<Module> targets = new HashSet<>();
1253                 for (String target : exports.targets()) {
1254                     Module m2 = findModule(target, nameToSource, nameToModule, parents);
1255                     if (m2 != null) {
1256                         // skip qualified export if already open to m2
1257                         if (openToTargets == null || !openToTargets.contains(m2)) {
1258                             addExports0(m, source, m2);
1259                             targets.add(m2);
1260                         }
1261                     }
1262                 }
1263                 if (!targets.isEmpty()) {
1264                     exportedPackages.put(source, targets);
1265                 }
1266 
1267             } else {
1268                 // unqualified exports
1269                 addExportsToAll0(m, source);
1270                 exportedPackages.put(source, EVERYONE_SET);
1271             }
1272         }
1273 
1274         if (!openPackages.isEmpty())
1275             m.openPackages = openPackages;
1276         if (!exportedPackages.isEmpty())
1277             m.exportedPackages = exportedPackages;
1278     }
1279 
1280     /**
1281      * Find the runtime Module with the given name. The module name is the
1282      * name of a target module in a qualified exports or opens directive.
1283      *
1284      * @param target The target module to find
1285      * @param nameToSource The modules in parent layers that are read
1286      * @param nameToModule The modules in the layer under construction
1287      * @param parents The parent layers
1288      */
1289     private static Module findModule(String target,
1290                                      Map<String, Module> nameToSource,
1291                                      Map<String, Module> nameToModule,
1292                                      List<ModuleLayer> parents) {
1293         Module m = nameToSource.get(target);
1294         if (m == null) {
1295             m = nameToModule.get(target);
1296             if (m == null) {
1297                 for (ModuleLayer parent : parents) {
1298                     m = parent.findModule(target).orElse(null);
1299                     if (m != null) break;
1300                 }
1301             }
1302         }
1303         return m;
1304     }
1305 
1306 
1307     // -- annotations --
1308 
1309     /**
1310      * {@inheritDoc}
1311      * This method returns {@code null} when invoked on an unnamed module.
1312      */
1313     @Override
1314     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
1315         return moduleInfoClass().getDeclaredAnnotation(annotationClass);
1316     }
1317 
1318     /**
1319      * {@inheritDoc}
1320      * This method returns an empty array when invoked on an unnamed module.
1321      */
1322     @Override
1323     public Annotation[] getAnnotations() {
1324         return moduleInfoClass().getAnnotations();
1325     }
1326 
1327     /**
1328      * {@inheritDoc}
1329      * This method returns an empty array when invoked on an unnamed module.
1330      */
1331     @Override
1332     public Annotation[] getDeclaredAnnotations() {
1333         return moduleInfoClass().getDeclaredAnnotations();
1334     }
1335 
1336     // cached class file with annotations
1337     private volatile Class<?> moduleInfoClass;
1338 
1339     private Class<?> moduleInfoClass() {
1340         Class<?> clazz = this.moduleInfoClass;
1341         if (clazz != null)
1342             return clazz;
1343 
1344         synchronized (this) {
1345             clazz = this.moduleInfoClass;
1346             if (clazz == null) {
1347                 if (isNamed()) {
1348                     PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass;
1349                     clazz = AccessController.doPrivileged(pa);
1350                 }
1351                 if (clazz == null) {
1352                     class DummyModuleInfo { }
1353                     clazz = DummyModuleInfo.class;
1354                 }
1355                 this.moduleInfoClass = clazz;
1356             }
1357             return clazz;
1358         }
1359     }
1360 
1361     private Class<?> loadModuleInfoClass() {
1362         Class<?> clazz = null;
1363         try (InputStream in = getResourceAsStream("module-info.class")) {
1364             if (in != null)
1365                 clazz = loadModuleInfoClass(in);
1366         } catch (Exception ignore) { }
1367         return clazz;
1368     }
1369 
1370     /**
1371      * Loads module-info.class as a package-private interface in a class loader
1372      * that is a child of this module's class loader.
1373      */
1374     private Class<?> loadModuleInfoClass(InputStream in) throws IOException {
1375         final String MODULE_INFO = "module-info";
1376 
1377         ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS
1378                                          + ClassWriter.COMPUTE_FRAMES);
1379 
1380         ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) {
1381             @Override
1382             public void visit(int version,
1383                               int access,
1384                               String name,
1385                               String signature,
1386                               String superName,
1387                               String[] interfaces) {
1388                 cw.visit(version,
1389                         Opcodes.ACC_INTERFACE
1390                             + Opcodes.ACC_ABSTRACT
1391                             + Opcodes.ACC_SYNTHETIC,
1392                         MODULE_INFO,
1393                         null,
1394                         "java/lang/Object",
1395                         null);
1396             }
1397             @Override
1398             public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
1399                 // keep annotations
1400                 return super.visitAnnotation(desc, visible);
1401             }
1402             @Override
1403             public void visitAttribute(Attribute attr) {
1404                 // drop non-annotation attributes
1405             }
1406         };
1407 
1408         ClassReader cr = new ClassReader(in);
1409         cr.accept(cv, 0);
1410         byte[] bytes = cw.toByteArray();
1411 
1412         ClassLoader cl = new ClassLoader(loader) {
1413             @Override
1414             protected Class<?> findClass(String cn)throws ClassNotFoundException {
1415                 if (cn.equals(MODULE_INFO)) {
1416                     return super.defineClass(cn, bytes, 0, bytes.length);
1417                 } else {
1418                     throw new ClassNotFoundException(cn);
1419                 }
1420             }
1421         };
1422 
1423         try {
1424             return cl.loadClass(MODULE_INFO);
1425         } catch (ClassNotFoundException e) {
1426             throw new InternalError(e);
1427         }
1428     }
1429 
1430 
1431     // -- misc --
1432 
1433 
1434     /**
1435      * Returns an input stream for reading a resource in this module.
1436      * The {@code name} parameter is a {@code '/'}-separated path name that
1437      * identifies the resource. As with {@link Class#getResourceAsStream
1438      * Class.getResourceAsStream}, this method delegates to the module's class
1439      * loader {@link ClassLoader#findResource(String,String)
1440      * findResource(String,String)} method, invoking it with the module name
1441      * (or {@code null} when the module is unnamed) and the name of the
1442      * resource. If the resource name has a leading slash then it is dropped
1443      * before delegation.
1444      *
1445      * <p> A resource in a named module may be <em>encapsulated</em> so that
1446      * it cannot be located by code in other modules. Whether a resource can be
1447      * located or not is determined as follows: </p>
1448      *
1449      * <ul>
1450      *     <li> If the resource name ends with  "{@code .class}" then it is not
1451      *     encapsulated. </li>
1452      *
1453      *     <li> A <em>package name</em> is derived from the resource name. If
1454      *     the package name is a {@link #getPackages() package} in the module
1455      *     then the resource can only be located by the caller of this method
1456      *     when the package is {@link #isOpen(String,Module) open} to at least
1457      *     the caller's module. If the resource is not in a package in the module
1458      *     then the resource is not encapsulated. </li>
1459      * </ul>
1460      *
1461      * <p> In the above, the <em>package name</em> for a resource is derived
1462      * from the subsequence of characters that precedes the last {@code '/'} in
1463      * the name and then replacing each {@code '/'} character in the subsequence
1464      * with {@code '.'}. A leading slash is ignored when deriving the package
1465      * name. As an example, the package name derived for a resource named
1466      * "{@code a/b/c/foo.properties}" is "{@code a.b.c}". A resource name
1467      * with the name "{@code META-INF/MANIFEST.MF}" is never encapsulated
1468      * because "{@code META-INF}" is not a legal package name. </p>
1469      *
1470      * <p> This method returns {@code null} if the resource is not in this
1471      * module, the resource is encapsulated and cannot be located by the caller,
1472      * or access to the resource is denied by the security manager. </p>
1473      *
1474      * @param  name
1475      *         The resource name
1476      *
1477      * @return An input stream for reading the resource or {@code null}
1478      *
1479      * @throws IOException
1480      *         If an I/O error occurs
1481      *
1482      * @see Class#getResourceAsStream(String)
1483      */
1484     @CallerSensitive
1485     public InputStream getResourceAsStream(String name) throws IOException {
1486         if (name.startsWith("/")) {
1487             name = name.substring(1);
1488         }
1489 
1490         if (isNamed() && Resources.canEncapsulate(name)) {
1491             Module caller = getCallerModule(Reflection.getCallerClass());
1492             if (caller != this && caller != Object.class.getModule()) {
1493                 String pn = Resources.toPackageName(name);
1494                 if (getPackages().contains(pn)) {
1495                     if (caller == null && !isOpen(pn)) {
1496                         // no caller, package not open
1497                         return null;
1498                     }
1499                     if (!isOpen(pn, caller)) {
1500                         // package not open to caller
1501                         return null;
1502                     }
1503                 }
1504             }
1505         }
1506 
1507         String mn = this.name;
1508 
1509         // special-case built-in class loaders to avoid URL connection
1510         if (loader == null) {
1511             return BootLoader.findResourceAsStream(mn, name);
1512         } else if (loader instanceof BuiltinClassLoader) {
1513             return ((BuiltinClassLoader) loader).findResourceAsStream(mn, name);
1514         }
1515 
1516         // locate resource in module
1517         JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
1518         URL url = jla.findResource(loader, mn, name);
1519         if (url != null) {
1520             try {
1521                 return url.openStream();
1522             } catch (SecurityException e) { }
1523         }
1524 
1525         return null;
1526     }
1527 
1528     /**
1529      * Returns the string representation of this module. For a named module,
1530      * the representation is the string {@code "module"}, followed by a space,
1531      * and then the module name. For an unnamed module, the representation is
1532      * the string {@code "unnamed module"}, followed by a space, and then an
1533      * implementation specific string that identifies the unnamed module.
1534      *
1535      * @return The string representation of this module
1536      */
1537     @Override
1538     public String toString() {
1539         if (isNamed()) {
1540             return "module " + name;
1541         } else {
1542             String id = Integer.toHexString(System.identityHashCode(this));
1543             return "unnamed module @" + id;
1544         }
1545     }
1546 
1547     /**
1548      * Returns the module that a given caller class is a member of. Returns
1549      * {@code null} if the caller is {@code null}.
1550      */
1551     private Module getCallerModule(Class<?> caller) {
1552         return (caller != null) ? caller.getModule() : null;
1553     }
1554 
1555 
1556     // -- native methods --
1557 
1558     // JVM_DefineModule
1559     private static native void defineModule0(Module module,
1560                                              boolean isOpen,
1561                                              String version,
1562                                              String location,
1563                                              String[] pns);
1564 
1565     // JVM_AddReadsModule
1566     private static native void addReads0(Module from, Module to);
1567 
1568     // JVM_AddModuleExports
1569     private static native void addExports0(Module from, String pn, Module to);
1570 
1571     // JVM_AddModuleExportsToAll
1572     private static native void addExportsToAll0(Module from, String pn);
1573 
1574     // JVM_AddModuleExportsToAllUnnamed
1575     private static native void addExportsToAllUnnamed0(Module from, String pn);
1576 
1577     // JVM_AddModulePackage
1578     private static native void addPackage0(Module m, String pn);
1579 }