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