< prev index next >

src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java

Print this page


  34 import java.lang.module.ResolvedModule;
  35 import java.net.URI;
  36 import java.nio.file.Path;
  37 import java.util.ArrayList;
  38 import java.util.Collections;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.Iterator;
  42 import java.util.LinkedHashMap;
  43 import java.util.List;
  44 import java.util.Map;
  45 import java.util.NoSuchElementException;
  46 import java.util.Objects;
  47 import java.util.Optional;
  48 import java.util.Set;
  49 import java.util.function.Function;
  50 import java.util.stream.Collectors;
  51 
  52 import jdk.internal.loader.BootLoader;
  53 import jdk.internal.loader.BuiltinClassLoader;


  54 import jdk.internal.access.JavaLangAccess;
  55 import jdk.internal.access.JavaLangModuleAccess;
  56 import jdk.internal.access.SharedSecrets;
  57 import jdk.internal.perf.PerfCounter;
  58 
  59 /**
  60  * Initializes/boots the module system.
  61  *
  62  * The {@link #boot() boot} method is called early in the startup to initialize
  63  * the module system. In summary, the boot method creates a Configuration by
  64  * resolving a set of module names specified via the launcher (or equivalent)
  65  * -m and --add-modules options. The modules are located on a module path that
  66  * is constructed from the upgrade module path, system modules, and application
  67  * module path. The Configuration is instantiated as the boot layer with each
  68  * module in the configuration defined to a class loader.
  69  */
  70 
  71 public final class ModuleBootstrap {
  72     private ModuleBootstrap() { }
  73 


 116             return ModuleFinder.ofSystem();
 117         } else {
 118             return finder;
 119         }
 120     }
 121 
 122     /**
 123      * Returns the ModuleFinder for the initial configuration.
 124      *
 125      * @apiNote Used to support "{@code java --list-modules}".
 126      */
 127     public static ModuleFinder limitedFinder() {
 128         ModuleFinder finder = limitedFinder;
 129         if (finder == null) {
 130             return unlimitedFinder();
 131         } else {
 132             return finder;
 133         }
 134     }
 135 

































































































 136     /**
 137      * Initialize the module system, returning the boot layer.
 138      *
 139      * @see java.lang.System#initPhase2(boolean, boolean)
 140      */
 141     public static ModuleLayer boot() throws Exception {
 142 
 143         Counters.start();




 144 
 145         // Step 0: Command line options
 146 
 147         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
 148         ModuleFinder appModulePath = finderFor("jdk.module.path");
 149         boolean isPatched = patcher.hasPatches();
 150 
 151         String mainModule = System.getProperty("jdk.module.main");
 152         Set<String> addModules = addModules();
 153         Set<String> limitModules = limitModules();
 154 
 155         PrintStream traceOutput = null;
 156         String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
 157         if (trace != null && Boolean.parseBoolean(trace))
 158             traceOutput = System.out;
 159 
 160         Counters.add("jdk.module.boot.0.commandLineTime");
 161 
 162         // Step 1: The observable system modules, either all system modules
 163         // or the system modules pre-generated for the initial module (the


 388                     if (upgradeModulePath != null
 389                             && upgradeModulePath.find(name).isPresent())
 390                         fail(name + ": cannot be loaded from upgrade module path");
 391                     if (!systemModuleFinder.find(name).isPresent())
 392                         fail(name + ": cannot be loaded from application module path");
 393                 }
 394             }
 395         }
 396 
 397         // check for split packages in the modules mapped to the built-in loaders
 398         if (hasSplitPackages || isPatched || haveModulePath) {
 399             checkSplitPackages(cf, clf);
 400         }
 401 
 402         // load/register the modules with the built-in class loaders
 403         loadModules(cf, clf);
 404         Counters.add("jdk.module.boot.5.loadModulesTime");
 405 
 406         // Step 6: Define all modules to the VM
 407 
 408         ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
 409         Counters.add("jdk.module.boot.6.layerCreateTime");
 410 
 411         // Step 7: Miscellaneous
 412 
 413         // check incubating status
 414         if (hasIncubatorModules || haveModulePath) {
 415             checkIncubatingStatus(cf);
 416         }
 417 
 418         // --add-reads, --add-exports/--add-opens, and --illegal-access
 419         addExtraReads(bootLayer);
 420         boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
 421 
 422         Map<String, Set<String>> concealedPackagesToOpen;
 423         Map<String, Set<String>> exportedPackagesToOpen;
 424         if (archivedModuleGraph != null) {
 425             concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
 426             exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
 427         } else {
 428             concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
 429             exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
 430         }

 431         addIllegalAccess(upgradeModulePath,
 432                          concealedPackagesToOpen,
 433                          exportedPackagesToOpen,
 434                          bootLayer,
 435                          extraExportsOrOpens);
 436         Counters.add("jdk.module.boot.7.adjustModulesTime");
 437 
 438         // save module finders for later use
 439         if (savedModuleFinder != null) {
 440             unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
 441             if (savedModuleFinder != finder)
 442                 limitedFinder = new SafeModuleFinder(finder);
 443         }
 444 
 445         // Module graph can be archived at CDS dump time. Only allow the
 446         // unnamed module case for now.
 447         if (canArchive && (mainModule == null)) {
 448             ArchivedModuleGraph.archive(
 449                     new ArchivedModuleGraph(hasSplitPackages,
 450                                             hasIncubatorModules,
 451                                             systemModuleFinder,
 452                                             cf,
 453                                             clf,
 454                                             concealedPackagesToOpen,
 455                                             exportedPackagesToOpen));





 456         }
 457 
 458         // total time to initialize
 459         Counters.publish("jdk.module.boot.totalTime");
 460 
 461         return bootLayer;
 462     }
 463 
 464     /**
 465      * Load/register the modules to the built-in class loaders.
 466      */
 467     private static void loadModules(Configuration cf,
 468                                     Function<String, ClassLoader> clf) {
 469         for (ResolvedModule resolvedModule : cf.modules()) {
 470             ModuleReference mref = resolvedModule.reference();
 471             String name = resolvedModule.name();
 472             ClassLoader loader = clf.apply(name);
 473             if (loader == null) {
 474                 // skip java.base as it is already loaded
 475                 if (!name.equals(JAVA_BASE)) {


 734                     if (opens) {
 735                         Modules.addOpensToAllUnnamed(m, pn);
 736                     } else {
 737                         Modules.addExportsToAllUnnamed(m, pn);
 738                     }
 739                 } else {
 740                     if (opens) {
 741                         Modules.addOpens(m, pn, other);
 742                     } else {
 743                         Modules.addExports(m, pn, other);
 744                     }
 745                 }
 746             }
 747         }
 748     }
 749 
 750     /**
 751      * Process the --illegal-access option (and its default) to open packages
 752      * of system modules in the boot layer to code in unnamed modules.
 753      */
 754     private static void addIllegalAccess(ModuleFinder upgradeModulePath,

 755                                          Map<String, Set<String>> concealedPackagesToOpen,
 756                                          Map<String, Set<String>> exportedPackagesToOpen,
 757                                          ModuleLayer bootLayer,
 758                                          boolean extraExportsOrOpens) {
 759         String value = getAndRemoveProperty("jdk.module.illegalAccess");
 760         IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
 761         if (value != null) {
 762             switch (value) {
 763                 case "deny":
 764                     return;
 765                 case "permit":
 766                     break;
 767                 case "warn":
 768                     mode = IllegalAccessLogger.Mode.WARN;
 769                     break;
 770                 case "debug":
 771                     mode = IllegalAccessLogger.Mode.DEBUG;
 772                     break;
 773                 default:
 774                     fail("Value specified to --illegal-access not recognized:"
 775                             + " '" + value + "'");
 776                     return;
 777             }
 778         }
 779         IllegalAccessLogger.Builder builder
 780             = new IllegalAccessLogger.Builder(mode, System.err);
 781 
 782         if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
 783             // need to generate (exploded build)
 784             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
 785             concealedPackagesToOpen = maps.concealedPackagesToOpen();
 786             exportedPackagesToOpen = maps.exportedPackagesToOpen();
 787         }
 788 
 789         // open specific packages in the system modules
 790         Set<String> emptySet = Set.of();
 791         for (Module m : bootLayer.modules()) {
 792             ModuleDescriptor descriptor = m.getDescriptor();
 793             String name = m.getName();
 794 
 795             // skip open modules
 796             if (descriptor.isOpen()) {


 824                     String pn = iterator.next();
 825                     if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
 826                         // exported package is opened to ALL-UNNAMED
 827                         iterator.remove();
 828                     }
 829                 }
 830             }
 831 
 832             // log reflective access to all types in concealed packages
 833             builder.logAccessToConcealedPackages(m, concealedPackages);
 834 
 835             // log reflective access to non-public members/types in exported packages
 836             builder.logAccessToExportedPackages(m, exportedPackages);
 837 
 838             // open the packages to unnamed modules
 839             JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 840             jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
 841         }
 842 
 843         builder.complete();

 844     }
 845 
 846     /**
 847      * Decodes the values of --add-reads, -add-exports, --add-opens or
 848      * --patch-modules options that are encoded in system properties.
 849      *
 850      * @param prefix the system property prefix
 851      * @praam regex the regex for splitting the RHS of the option value
 852      */
 853     private static Map<String, List<String>> decode(String prefix,
 854                                                     String regex,
 855                                                     boolean allowDuplicates) {
 856         int index = 0;
 857         // the system property is removed after decoding
 858         String value = getAndRemoveProperty(prefix + index);
 859         if (value == null)
 860             return Map.of();
 861 
 862         Map<String, List<String>> map = new HashMap<>();
 863 




  34 import java.lang.module.ResolvedModule;
  35 import java.net.URI;
  36 import java.nio.file.Path;
  37 import java.util.ArrayList;
  38 import java.util.Collections;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.Iterator;
  42 import java.util.LinkedHashMap;
  43 import java.util.List;
  44 import java.util.Map;
  45 import java.util.NoSuchElementException;
  46 import java.util.Objects;
  47 import java.util.Optional;
  48 import java.util.Set;
  49 import java.util.function.Function;
  50 import java.util.stream.Collectors;
  51 
  52 import jdk.internal.loader.BootLoader;
  53 import jdk.internal.loader.BuiltinClassLoader;
  54 import jdk.internal.loader.ClassLoaders;
  55 import jdk.internal.misc.VM;
  56 import jdk.internal.access.JavaLangAccess;
  57 import jdk.internal.access.JavaLangModuleAccess;
  58 import jdk.internal.access.SharedSecrets;
  59 import jdk.internal.perf.PerfCounter;
  60 
  61 /**
  62  * Initializes/boots the module system.
  63  *
  64  * The {@link #boot() boot} method is called early in the startup to initialize
  65  * the module system. In summary, the boot method creates a Configuration by
  66  * resolving a set of module names specified via the launcher (or equivalent)
  67  * -m and --add-modules options. The modules are located on a module path that
  68  * is constructed from the upgrade module path, system modules, and application
  69  * module path. The Configuration is instantiated as the boot layer with each
  70  * module in the configuration defined to a class loader.
  71  */
  72 
  73 public final class ModuleBootstrap {
  74     private ModuleBootstrap() { }
  75 


 118             return ModuleFinder.ofSystem();
 119         } else {
 120             return finder;
 121         }
 122     }
 123 
 124     /**
 125      * Returns the ModuleFinder for the initial configuration.
 126      *
 127      * @apiNote Used to support "{@code java --list-modules}".
 128      */
 129     public static ModuleFinder limitedFinder() {
 130         ModuleFinder finder = limitedFinder;
 131         if (finder == null) {
 132             return unlimitedFinder();
 133         } else {
 134             return finder;
 135         }
 136     }
 137 
 138     private static class ArchivedBootLayer {
 139         private static ArchivedBootLayer archivedBootLayer;
 140 
 141         private final ModuleLayer bootLayer;
 142         private final ModuleFinder limitedFinder;
 143         private final IllegalAccessLogger.Builder builder;
 144         private final ModuleFinder unlimitedFinder;
 145         private final ServicesCatalog platformCatalog;
 146         private final ServicesCatalog appCatalog;
 147 
 148         public ArchivedBootLayer(ModuleLayer bootLayer,
 149                                  ModuleFinder limitedFinder,
 150                                  ModuleFinder unlimitedFinder,
 151                                  IllegalAccessLogger.Builder builder) {
 152             this.bootLayer = bootLayer;
 153             this.limitedFinder = limitedFinder;
 154             this.unlimitedFinder = unlimitedFinder;
 155             this.builder = builder;
 156 
 157             this.platformCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.platformClassLoader());
 158             this.appCatalog = ServicesCatalog.getServicesCatalog(ClassLoaders.appClassLoader());
 159         }
 160 
 161         static ArchivedBootLayer get() {
 162             // The VM will initialize archivedBootLayer only if MetaspaceShared::use_full_module_graph() is true.
 163             return archivedBootLayer;
 164         }
 165 
 166         static void archive(ArchivedBootLayer layer) {
 167             archivedBootLayer = layer;
 168         }
 169 
 170         static {
 171             VM.initializeFromArchive(ArchivedBootLayer.class);
 172         }
 173     }
 174 
 175     private static boolean hasProperty(String key) {
 176         return System.getProperty(key) != null;
 177     }
 178 
 179     private static boolean mayUseArchivedBootLayer() {
 180         // If these properties are set, we cannot use the archived boot layer.
 181         // The VM should have already checked this before initializing
 182         // ArchivedBootLayer::archivedBootLayer.
 183         if (hasProperty("jdk.module.upgrade.path") ||
 184             hasProperty("jdk.module.main") ||
 185             hasProperty("jdk.module.limitmods") ||
 186             hasProperty("jdk.module.validation") ||
 187             hasProperty("jdk.module.showModuleResolution") ||
 188             hasProperty("jdk.module.illegalAccess") ||
 189             hasProperty("java.system.class.loader") ||
 190             hasProperty("jdk.module.addexports.0") || 
 191             hasProperty("jdk.module.addopens.0") ||
 192             hasProperty("jdk.module.addreads.0") ||
 193             hasProperty("jdk.module.patch.0") ||
 194             hasProperty("jdk.module.addmods.0")) {
 195             return false;
 196         } else {
 197             return true;
 198         }
 199     }
 200 
 201     private static ModuleLayer getArchivedBootLayer() {
 202         ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
 203         if (archivedBootLayer != null) {
 204             assert mayUseArchivedBootLayer();
 205             Counters.add("jdk.module.boot.0.archivedBootLayer");
 206             limitedFinder = archivedBootLayer.limitedFinder;
 207             unlimitedFinder = archivedBootLayer.unlimitedFinder;
 208             ModuleLayer bootLayer = archivedBootLayer.bootLayer;
 209 
 210             // Trigger BootLoader.<clinit> 
 211             BootLoader.getUnnamedModule();
 212 
 213             // BootLoader.SERVICES_CATALOG is saved/restored separately in BootLoader.java
 214             ServicesCatalog.setServicesCatalog(ClassLoaders.platformClassLoader(),
 215                                                archivedBootLayer.platformCatalog);
 216             ServicesCatalog.setServicesCatalog(ClassLoaders.appClassLoader(),
 217                                                archivedBootLayer.appCatalog);
 218 
 219             JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 220             jla.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
 221 
 222             IllegalAccessLogger.Builder builder = archivedBootLayer.builder;
 223             if (builder != null) {
 224                 builder.complete();
 225             }
 226 
 227             Counters.publish("jdk.module.boot.totalTime");
 228             return bootLayer;
 229         }
 230 
 231         return null;
 232     }
 233 
 234 
 235     /**
 236      * Initialize the module system, returning the boot layer.
 237      *
 238      * @see java.lang.System#initPhase2(boolean, boolean)
 239      */
 240     public static ModuleLayer boot() throws Exception {
 241 
 242         Counters.start();
 243         ModuleLayer bootLayer = getArchivedBootLayer();
 244         if (bootLayer != null) {
 245             return bootLayer;
 246         }
 247 
 248         // Step 0: Command line options
 249 
 250         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
 251         ModuleFinder appModulePath = finderFor("jdk.module.path");
 252         boolean isPatched = patcher.hasPatches();
 253 
 254         String mainModule = System.getProperty("jdk.module.main");
 255         Set<String> addModules = addModules();
 256         Set<String> limitModules = limitModules();
 257 
 258         PrintStream traceOutput = null;
 259         String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
 260         if (trace != null && Boolean.parseBoolean(trace))
 261             traceOutput = System.out;
 262 
 263         Counters.add("jdk.module.boot.0.commandLineTime");
 264 
 265         // Step 1: The observable system modules, either all system modules
 266         // or the system modules pre-generated for the initial module (the


 491                     if (upgradeModulePath != null
 492                             && upgradeModulePath.find(name).isPresent())
 493                         fail(name + ": cannot be loaded from upgrade module path");
 494                     if (!systemModuleFinder.find(name).isPresent())
 495                         fail(name + ": cannot be loaded from application module path");
 496                 }
 497             }
 498         }
 499 
 500         // check for split packages in the modules mapped to the built-in loaders
 501         if (hasSplitPackages || isPatched || haveModulePath) {
 502             checkSplitPackages(cf, clf);
 503         }
 504 
 505         // load/register the modules with the built-in class loaders
 506         loadModules(cf, clf);
 507         Counters.add("jdk.module.boot.5.loadModulesTime");
 508 
 509         // Step 6: Define all modules to the VM
 510 
 511         bootLayer = ModuleLayer.empty().defineModules(cf, clf);
 512         Counters.add("jdk.module.boot.6.layerCreateTime");
 513 
 514         // Step 7: Miscellaneous
 515 
 516         // check incubating status
 517         if (hasIncubatorModules || haveModulePath) {
 518             checkIncubatingStatus(cf);
 519         }
 520 
 521         // --add-reads, --add-exports/--add-opens, and --illegal-access
 522         addExtraReads(bootLayer);
 523         boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
 524 
 525         Map<String, Set<String>> concealedPackagesToOpen;
 526         Map<String, Set<String>> exportedPackagesToOpen;
 527         if (archivedModuleGraph != null) {
 528             concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
 529             exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
 530         } else {
 531             concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
 532             exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
 533         }
 534         IllegalAccessLogger.Builder builder =
 535             addIllegalAccess(upgradeModulePath,
 536                              concealedPackagesToOpen,
 537                              exportedPackagesToOpen,
 538                              bootLayer,
 539                              extraExportsOrOpens);
 540         Counters.add("jdk.module.boot.7.adjustModulesTime");
 541 
 542         // save module finders for later use
 543         if (savedModuleFinder != null) {
 544             unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
 545             if (savedModuleFinder != finder)
 546                 limitedFinder = new SafeModuleFinder(finder);
 547         }
 548 
 549         // Module graph can be archived at CDS dump time. Only allow the
 550         // unnamed module case for now.
 551         if (canArchive && (mainModule == null)) {
 552             ArchivedModuleGraph.archive(
 553                     new ArchivedModuleGraph(hasSplitPackages,
 554                                             hasIncubatorModules,
 555                                             systemModuleFinder,
 556                                             cf,
 557                                             clf,
 558                                             concealedPackagesToOpen,
 559                                             exportedPackagesToOpen));
 560             ArchivedBootLayer.archive(
 561                     new ArchivedBootLayer(bootLayer,
 562                                           limitedFinder,
 563                                           unlimitedFinder,
 564                                           builder));
 565         }
 566 
 567         // total time to initialize
 568         Counters.publish("jdk.module.boot.totalTime");
 569 
 570         return bootLayer;
 571     }
 572 
 573     /**
 574      * Load/register the modules to the built-in class loaders.
 575      */
 576     private static void loadModules(Configuration cf,
 577                                     Function<String, ClassLoader> clf) {
 578         for (ResolvedModule resolvedModule : cf.modules()) {
 579             ModuleReference mref = resolvedModule.reference();
 580             String name = resolvedModule.name();
 581             ClassLoader loader = clf.apply(name);
 582             if (loader == null) {
 583                 // skip java.base as it is already loaded
 584                 if (!name.equals(JAVA_BASE)) {


 843                     if (opens) {
 844                         Modules.addOpensToAllUnnamed(m, pn);
 845                     } else {
 846                         Modules.addExportsToAllUnnamed(m, pn);
 847                     }
 848                 } else {
 849                     if (opens) {
 850                         Modules.addOpens(m, pn, other);
 851                     } else {
 852                         Modules.addExports(m, pn, other);
 853                     }
 854                 }
 855             }
 856         }
 857     }
 858 
 859     /**
 860      * Process the --illegal-access option (and its default) to open packages
 861      * of system modules in the boot layer to code in unnamed modules.
 862      */
 863     private static IllegalAccessLogger.Builder
 864         addIllegalAccess(ModuleFinder upgradeModulePath,
 865                          Map<String, Set<String>> concealedPackagesToOpen,
 866                          Map<String, Set<String>> exportedPackagesToOpen,
 867                          ModuleLayer bootLayer,
 868                          boolean extraExportsOrOpens) {
 869         String value = getAndRemoveProperty("jdk.module.illegalAccess");
 870         IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
 871         if (value != null) {
 872             switch (value) {
 873                 case "deny":
 874                     return null;
 875                 case "permit":
 876                     break;
 877                 case "warn":
 878                     mode = IllegalAccessLogger.Mode.WARN;
 879                     break;
 880                 case "debug":
 881                     mode = IllegalAccessLogger.Mode.DEBUG;
 882                     break;
 883                 default:
 884                     fail("Value specified to --illegal-access not recognized:"
 885                             + " '" + value + "'");
 886                     return null;
 887             }
 888         }
 889         IllegalAccessLogger.Builder builder
 890             = new IllegalAccessLogger.Builder(mode, System.err);
 891 
 892         if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
 893             // need to generate (exploded build)
 894             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
 895             concealedPackagesToOpen = maps.concealedPackagesToOpen();
 896             exportedPackagesToOpen = maps.exportedPackagesToOpen();
 897         }
 898 
 899         // open specific packages in the system modules
 900         Set<String> emptySet = Set.of();
 901         for (Module m : bootLayer.modules()) {
 902             ModuleDescriptor descriptor = m.getDescriptor();
 903             String name = m.getName();
 904 
 905             // skip open modules
 906             if (descriptor.isOpen()) {


 934                     String pn = iterator.next();
 935                     if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
 936                         // exported package is opened to ALL-UNNAMED
 937                         iterator.remove();
 938                     }
 939                 }
 940             }
 941 
 942             // log reflective access to all types in concealed packages
 943             builder.logAccessToConcealedPackages(m, concealedPackages);
 944 
 945             // log reflective access to non-public members/types in exported packages
 946             builder.logAccessToExportedPackages(m, exportedPackages);
 947 
 948             // open the packages to unnamed modules
 949             JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 950             jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
 951         }
 952 
 953         builder.complete();
 954         return builder;
 955     }
 956 
 957     /**
 958      * Decodes the values of --add-reads, -add-exports, --add-opens or
 959      * --patch-modules options that are encoded in system properties.
 960      *
 961      * @param prefix the system property prefix
 962      * @praam regex the regex for splitting the RHS of the option value
 963      */
 964     private static Map<String, List<String>> decode(String prefix,
 965                                                     String regex,
 966                                                     boolean allowDuplicates) {
 967         int index = 0;
 968         // the system property is removed after decoding
 969         String value = getAndRemoveProperty(prefix + index);
 970         if (value == null)
 971             return Map.of();
 972 
 973         Map<String, List<String>> map = new HashMap<>();
 974 


< prev index next >