< prev index next >

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

Print this page


  25 
  26 package jdk.internal.module;
  27 
  28 import java.io.File;
  29 import java.io.PrintStream;
  30 import java.lang.module.Configuration;
  31 import java.lang.module.ModuleDescriptor;
  32 import java.lang.module.ModuleFinder;
  33 import java.lang.module.ModuleReference;
  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 
  74     private static final String JAVA_BASE = "java.base";
  75 
  76     // the token for "all default modules"
  77     private static final String ALL_DEFAULT = "ALL-DEFAULT";
  78 
  79     // the token for "all unnamed modules"
  80     private static final String ALL_UNNAMED = "ALL-UNNAMED";
  81 
  82     // the token for "all system modules"
  83     private static final String ALL_SYSTEM = "ALL-SYSTEM";
  84 
  85     // the token for "all modules on the module path"
  86     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
  87 
  88     // access to java.lang/module
  89     private static final JavaLangModuleAccess JLMA
  90         = SharedSecrets.getJavaLangModuleAccess();
  91 
  92     // The ModulePatcher for the initial configuration
  93     private static final ModulePatcher patcher = initModulePatcher();
  94 
  95     /**
  96      * Returns the ModulePatcher for the initial configuration.
  97      */
  98     public static ModulePatcher patcher() {
  99         return patcher;
 100     }
 101 
 102     // ModuleFinders for the initial configuration
 103     private static volatile ModuleFinder unlimitedFinder;
 104     private static volatile ModuleFinder limitedFinder;
 105 
 106     /**
 107      * Returns the ModuleFinder for the initial configuration before
 108      * observability is limited by the --limit-modules command line option.
 109      *
 110      * @apiNote Used to support locating modules {@code java.instrument} and


 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
 164         // initial module may be the unnamed module). If the system modules


 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)) {
 476                     BootLoader.loadModule(mref);
 477                 }
 478             } else if (loader instanceof BuiltinClassLoader) {
 479                 ((BuiltinClassLoader) loader).loadModule(mref);


 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()) {


 819                         exportedPackages.add(pn);
 820                     }
 821                 }
 822                 iterator = exportedPackages.iterator();
 823                 while (iterator.hasNext()) {
 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 


 888                 }
 889             }
 890             if (ntargets == 0)
 891                 fail("Target must be specified: " + option(prefix) + " " + value);
 892 
 893             index++;
 894             value = getAndRemoveProperty(prefix + index);
 895         }
 896 
 897         return map;
 898     }
 899 
 900     /**
 901      * Decodes the values of --add-reads, -add-exports or --add-opens
 902      * which use the "," to separate the RHS of the option value.
 903      */
 904     private static Map<String, List<String>> decode(String prefix) {
 905         return decode(prefix, ",", true);
 906     }
 907 








 908     /**
 909      * Gets and remove the named system property
 910      */
 911     private static String getAndRemoveProperty(String key) {
 912         return (String)System.getProperties().remove(key);
 913     }
 914 
 915     /**
 916      * Checks incubating status of modules in the configuration
 917      */
 918     private static void checkIncubatingStatus(Configuration cf) {
 919         String incubating = null;
 920         for (ResolvedModule resolvedModule : cf.modules()) {
 921             ModuleReference mref = resolvedModule.reference();
 922 
 923             // emit warning if the WARN_INCUBATING module resolution bit set
 924             if (ModuleResolution.hasIncubatingWarning(mref)) {
 925                 String mn = mref.descriptor().name();
 926                 if (incubating == null) {
 927                     incubating = mn;
 928                 } else {
 929                     incubating += ", " + mn;
 930                 }
 931             }
 932         }




  25 
  26 package jdk.internal.module;
  27 
  28 import java.io.File;
  29 import java.io.PrintStream;
  30 import java.lang.module.Configuration;
  31 import java.lang.module.ModuleDescriptor;
  32 import java.lang.module.ModuleFinder;
  33 import java.lang.module.ModuleReference;
  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.Objects;
  46 import java.util.Optional;
  47 import java.util.Set;
  48 import java.util.function.Function;
  49 import java.util.stream.Collectors;
  50 


  51 import jdk.internal.access.JavaLangAccess;
  52 import jdk.internal.access.JavaLangModuleAccess;
  53 import jdk.internal.access.SharedSecrets;
  54 import jdk.internal.loader.BootLoader;
  55 import jdk.internal.loader.BuiltinClassLoader;
  56 import jdk.internal.loader.ClassLoaders;
  57 import jdk.internal.misc.VM;
  58 import jdk.internal.perf.PerfCounter;
  59 
  60 /**
  61  * Initializes/boots the module system.
  62  *
  63  * The {@link #boot() boot} method is called early in the startup to initialize
  64  * the module system. In summary, the boot method creates a Configuration by
  65  * resolving a set of module names specified via the launcher (or equivalent)
  66  * -m and --add-modules options. The modules are located on a module path that
  67  * is constructed from the upgrade module path, system modules, and application
  68  * module path. The Configuration is instantiated as the boot layer with each
  69  * module in the configuration defined to a class loader.
  70  */
  71 
  72 public final class ModuleBootstrap {
  73     private ModuleBootstrap() { }
  74 
  75     private static final String JAVA_BASE = "java.base";
  76 
  77     // the token for "all default modules"
  78     private static final String ALL_DEFAULT = "ALL-DEFAULT";
  79 
  80     // the token for "all unnamed modules"
  81     private static final String ALL_UNNAMED = "ALL-UNNAMED";
  82 
  83     // the token for "all system modules"
  84     private static final String ALL_SYSTEM = "ALL-SYSTEM";
  85 
  86     // the token for "all modules on the module path"
  87     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
  88 
  89     // access to java.lang/module
  90     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
  91     private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
  92 
  93     // The ModulePatcher for the initial configuration
  94     private static final ModulePatcher patcher = initModulePatcher();
  95 
  96     /**
  97      * Returns the ModulePatcher for the initial configuration.
  98      */
  99     public static ModulePatcher patcher() {
 100         return patcher;
 101     }
 102 
 103     // ModuleFinders for the initial configuration
 104     private static volatile ModuleFinder unlimitedFinder;
 105     private static volatile ModuleFinder limitedFinder;
 106 
 107     /**
 108      * Returns the ModuleFinder for the initial configuration before
 109      * observability is limited by the --limit-modules command line option.
 110      *
 111      * @apiNote Used to support locating modules {@code java.instrument} and


 118         } else {
 119             return finder;
 120         }
 121     }
 122 
 123     /**
 124      * Returns the ModuleFinder for the initial configuration.
 125      *
 126      * @apiNote Used to support "{@code java --list-modules}".
 127      */
 128     public static ModuleFinder limitedFinder() {
 129         ModuleFinder finder = limitedFinder;
 130         if (finder == null) {
 131             return unlimitedFinder();
 132         } else {
 133             return finder;
 134         }
 135     }
 136 
 137     /**
 138      * Returns true if the archived boot layer can be used. The system properties
 139      * are checked in the order that they are used by boot2.
 140      */
 141     private static boolean canUseArchivedBootLayer() {
 142         return getProperty("jdk.module.upgrade.path") == null &&
 143                getProperty("jdk.module.path") == null &&
 144                getProperty("jdk.module.patch.0") == null &&    // --patch-module
 145                getProperty("jdk.module.main") == null &&
 146                getProperty("jdk.module.addmods.0") == null  && // --add-modules
 147                getProperty("jdk.module.limitmods") == null &&
 148                getProperty("jdk.module.addreads.0") == null &&    // --add-reads
 149                getProperty("jdk.module.addexports.0") == null &&  // --add-exports
 150                getProperty("jdk.module.addopens.0") == null &&    // --add-opens
 151                getProperty("jdk.module.illegalAccess") == null;
 152     }
 153 
 154     /**
 155      * Initialize the module system, returning the boot layer. The boot layer
 156      * is obtained from the CDS archive if possible, otherwise it is generated
 157      * from the module graph.
 158      *
 159      * @see java.lang.System#initPhase2(boolean, boolean)
 160      */
 161     public static ModuleLayer boot() {

 162         Counters.start();
 163 
 164         ModuleLayer bootLayer;
 165         ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
 166         if (archivedBootLayer != null) {
 167             assert canUseArchivedBootLayer();
 168             bootLayer = archivedBootLayer.bootLayer();
 169             BootLoader.getUnnamedModule(); // trigger <clinit> of BootLoader.
 170             VM.defineArchivedModules(ClassLoaders.platformClassLoader(), ClassLoaders.appClassLoader());
 171 
 172             // assume boot layer has at least one module providing a service
 173             // that is mapped to the application class loader.
 174             JLA.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
 175 
 176             // IllegalAccessLogger needs to be set
 177             var illegalAccessLoggerBuilder = archivedBootLayer.illegalAccessLoggerBuilder();
 178             if (illegalAccessLoggerBuilder != null) {
 179                 illegalAccessLoggerBuilder.complete();
 180             }
 181         } else {
 182             bootLayer = boot2();
 183         }
 184 
 185         Counters.publish("jdk.module.boot.totalTime");
 186         return bootLayer;
 187     }
 188 
 189     private static ModuleLayer boot2() {
 190         // Step 0: Command line options
 191 
 192         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
 193         ModuleFinder appModulePath = finderFor("jdk.module.path");
 194         boolean isPatched = patcher.hasPatches();
 195 
 196         String mainModule = System.getProperty("jdk.module.main");
 197         Set<String> addModules = addModules();
 198         Set<String> limitModules = limitModules();
 199 
 200         PrintStream traceOutput = null;
 201         String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
 202         if (trace != null && Boolean.parseBoolean(trace))
 203             traceOutput = System.out;
 204 
 205         Counters.add("jdk.module.boot.0.commandLineTime");
 206 
 207         // Step 1: The observable system modules, either all system modules
 208         // or the system modules pre-generated for the initial module (the
 209         // initial module may be the unnamed module). If the system modules


 456         // Step 7: Miscellaneous
 457 
 458         // check incubating status
 459         if (hasIncubatorModules || haveModulePath) {
 460             checkIncubatingStatus(cf);
 461         }
 462 
 463         // --add-reads, --add-exports/--add-opens, and --illegal-access
 464         addExtraReads(bootLayer);
 465         boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
 466 
 467         Map<String, Set<String>> concealedPackagesToOpen;
 468         Map<String, Set<String>> exportedPackagesToOpen;
 469         if (archivedModuleGraph != null) {
 470             concealedPackagesToOpen = archivedModuleGraph.concealedPackagesToOpen();
 471             exportedPackagesToOpen = archivedModuleGraph.exportedPackagesToOpen();
 472         } else {
 473             concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
 474             exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
 475         }
 476         IllegalAccessLogger.Builder builder =
 477             addIllegalAccess(upgradeModulePath,
 478                              concealedPackagesToOpen,
 479                              exportedPackagesToOpen,
 480                              bootLayer,
 481                              extraExportsOrOpens);
 482         Counters.add("jdk.module.boot.7.adjustModulesTime");
 483 
 484         // save module finders for later use
 485         if (savedModuleFinder != null) {
 486             unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
 487             if (savedModuleFinder != finder)
 488                 limitedFinder = new SafeModuleFinder(finder);
 489         }
 490 
 491         // Archive module graph and boot layer can be archived at CDS dump time.
 492         // Only allow the unnamed module case for now.
 493         if (canArchive && (mainModule == null)) {
 494             ArchivedModuleGraph.archive(hasSplitPackages,

 495                                         hasIncubatorModules,
 496                                         systemModuleFinder,
 497                                         cf,
 498                                         clf,
 499                                         concealedPackagesToOpen,
 500                                         exportedPackagesToOpen);

 501 
 502             if (!hasSplitPackages && !hasIncubatorModules) {
 503                 ArchivedBootLayer.archive(bootLayer, builder);
 504             }
 505         }
 506 
 507         return bootLayer;
 508     }
 509 
 510     /**
 511      * Load/register the modules to the built-in class loaders.
 512      */
 513     private static void loadModules(Configuration cf,
 514                                     Function<String, ClassLoader> clf) {
 515         for (ResolvedModule resolvedModule : cf.modules()) {
 516             ModuleReference mref = resolvedModule.reference();
 517             String name = resolvedModule.name();
 518             ClassLoader loader = clf.apply(name);
 519             if (loader == null) {
 520                 // skip java.base as it is already loaded
 521                 if (!name.equals(JAVA_BASE)) {
 522                     BootLoader.loadModule(mref);
 523                 }
 524             } else if (loader instanceof BuiltinClassLoader) {
 525                 ((BuiltinClassLoader) loader).loadModule(mref);


 780                     if (opens) {
 781                         Modules.addOpensToAllUnnamed(m, pn);
 782                     } else {
 783                         Modules.addExportsToAllUnnamed(m, pn);
 784                     }
 785                 } else {
 786                     if (opens) {
 787                         Modules.addOpens(m, pn, other);
 788                     } else {
 789                         Modules.addExports(m, pn, other);
 790                     }
 791                 }
 792             }
 793         }
 794     }
 795 
 796     /**
 797      * Process the --illegal-access option (and its default) to open packages
 798      * of system modules in the boot layer to code in unnamed modules.
 799      */
 800     private static IllegalAccessLogger.Builder
 801         addIllegalAccess(ModuleFinder upgradeModulePath,
 802                          Map<String, Set<String>> concealedPackagesToOpen,
 803                          Map<String, Set<String>> exportedPackagesToOpen,
 804                          ModuleLayer bootLayer,
 805                          boolean extraExportsOrOpens) {
 806         String value = getAndRemoveProperty("jdk.module.illegalAccess");
 807         IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
 808         if (value != null) {
 809             switch (value) {
 810                 case "deny":
 811                     return null;
 812                 case "permit":
 813                     break;
 814                 case "warn":
 815                     mode = IllegalAccessLogger.Mode.WARN;
 816                     break;
 817                 case "debug":
 818                     mode = IllegalAccessLogger.Mode.DEBUG;
 819                     break;
 820                 default:
 821                     fail("Value specified to --illegal-access not recognized:"
 822                             + " '" + value + "'");
 823                     return null;
 824             }
 825         }
 826         IllegalAccessLogger.Builder builder
 827             = new IllegalAccessLogger.Builder(mode, System.err);
 828 
 829         if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
 830             // need to generate (exploded build)
 831             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
 832             concealedPackagesToOpen = maps.concealedPackagesToOpen();
 833             exportedPackagesToOpen = maps.exportedPackagesToOpen();
 834         }
 835 
 836         // open specific packages in the system modules
 837         Set<String> emptySet = Set.of();
 838         for (Module m : bootLayer.modules()) {
 839             ModuleDescriptor descriptor = m.getDescriptor();
 840             String name = m.getName();
 841 
 842             // skip open modules
 843             if (descriptor.isOpen()) {


 866                         exportedPackages.add(pn);
 867                     }
 868                 }
 869                 iterator = exportedPackages.iterator();
 870                 while (iterator.hasNext()) {
 871                     String pn = iterator.next();
 872                     if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
 873                         // exported package is opened to ALL-UNNAMED
 874                         iterator.remove();
 875                     }
 876                 }
 877             }
 878 
 879             // log reflective access to all types in concealed packages
 880             builder.logAccessToConcealedPackages(m, concealedPackages);
 881 
 882             // log reflective access to non-public members/types in exported packages
 883             builder.logAccessToExportedPackages(m, exportedPackages);
 884 
 885             // open the packages to unnamed modules
 886             JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);

 887         }
 888 
 889         builder.complete();
 890         return builder;
 891     }
 892 
 893     /**
 894      * Decodes the values of --add-reads, -add-exports, --add-opens or
 895      * --patch-modules options that are encoded in system properties.
 896      *
 897      * @param prefix the system property prefix
 898      * @praam regex the regex for splitting the RHS of the option value
 899      */
 900     private static Map<String, List<String>> decode(String prefix,
 901                                                     String regex,
 902                                                     boolean allowDuplicates) {
 903         int index = 0;
 904         // the system property is removed after decoding
 905         String value = getAndRemoveProperty(prefix + index);
 906         if (value == null)
 907             return Map.of();
 908 
 909         Map<String, List<String>> map = new HashMap<>();
 910 


 935                 }
 936             }
 937             if (ntargets == 0)
 938                 fail("Target must be specified: " + option(prefix) + " " + value);
 939 
 940             index++;
 941             value = getAndRemoveProperty(prefix + index);
 942         }
 943 
 944         return map;
 945     }
 946 
 947     /**
 948      * Decodes the values of --add-reads, -add-exports or --add-opens
 949      * which use the "," to separate the RHS of the option value.
 950      */
 951     private static Map<String, List<String>> decode(String prefix) {
 952         return decode(prefix, ",", true);
 953     }
 954 
 955 
 956     /**
 957      * Gets the named system property
 958      */
 959     private static String getProperty(String key) {
 960         return System.getProperty(key);
 961     }
 962 
 963     /**
 964      * Gets and remove the named system property
 965      */
 966     private static String getAndRemoveProperty(String key) {
 967         return (String) System.getProperties().remove(key);
 968     }
 969 
 970     /**
 971      * Checks incubating status of modules in the configuration
 972      */
 973     private static void checkIncubatingStatus(Configuration cf) {
 974         String incubating = null;
 975         for (ResolvedModule resolvedModule : cf.modules()) {
 976             ModuleReference mref = resolvedModule.reference();
 977 
 978             // emit warning if the WARN_INCUBATING module resolution bit set
 979             if (ModuleResolution.hasIncubatingWarning(mref)) {
 980                 String mn = mref.descriptor().name();
 981                 if (incubating == null) {
 982                     incubating = mn;
 983                 } else {
 984                     incubating += ", " + mn;
 985                 }
 986             }
 987         }


< prev index next >