< prev index next >

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

Print this page
rev 57943 : 8238599: Refactor and simplify implAddOpensToAllUnnamed
Reviewed-by: alanb


 783                     break;
 784                 case "debug":
 785                     mode = IllegalAccessLogger.Mode.DEBUG;
 786                     break;
 787                 default:
 788                     fail("Value specified to --illegal-access not recognized:"
 789                             + " '" + value + "'");
 790                     return;
 791             }
 792         }
 793         IllegalAccessLogger.Builder builder
 794             = new IllegalAccessLogger.Builder(mode, System.err);
 795 
 796         if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
 797             // need to generate (exploded build)
 798             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
 799             concealedPackagesToOpen = maps.concealedPackagesToOpen();
 800             exportedPackagesToOpen = maps.exportedPackagesToOpen();
 801         }
 802 


 803         // open specific packages in the system modules
 804         for (Module m : bootLayer.modules()) {
 805             ModuleDescriptor descriptor = m.getDescriptor();
 806             String name = m.getName();
 807 
 808             // skip open modules
 809             if (descriptor.isOpen()) {
 810                 continue;
 811             }
 812 
 813             // skip modules loaded from the upgrade module path
 814             if (upgradeModulePath != null
 815                 && upgradeModulePath.find(name).isPresent()) {
 816                 continue;
 817             }
 818 
 819             Set<String> concealedPackages = concealedPackagesToOpen.getOrDefault(name, Set.of());
 820             Set<String> exportedPackages = exportedPackagesToOpen.getOrDefault(name, Set.of());
 821 
 822             // refresh the set of concealed and exported packages if needed
 823             if (extraExportsOrOpens) {
 824                 concealedPackages = new HashSet<>(concealedPackages);
 825                 exportedPackages = new HashSet<>(exportedPackages);
 826                 Iterator<String> iterator = concealedPackages.iterator();
 827                 while (iterator.hasNext()) {
 828                     String pn = iterator.next();
 829                     if (m.isExported(pn, BootLoader.getUnnamedModule())) {
 830                         // concealed package is exported to ALL-UNNAMED
 831                         iterator.remove();
 832                         exportedPackages.add(pn);
 833                     }
 834                 }
 835                 iterator = exportedPackages.iterator();
 836                 while (iterator.hasNext()) {
 837                     String pn = iterator.next();
 838                     if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
 839                         // exported package is opened to ALL-UNNAMED
 840                         iterator.remove();
 841                     }
 842                 }
 843             }
 844 
 845             // log reflective access to all types in concealed packages
 846             builder.logAccessToConcealedPackages(m, concealedPackages);
 847 
 848             // log reflective access to non-public members/types in exported packages
 849             builder.logAccessToExportedPackages(m, exportedPackages);
 850 
 851             // open the packages to unnamed modules
 852             JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 853             jla.addOpensToAllUnnamed(m, concat(concealedPackages.iterator(),
 854                                                exportedPackages.iterator()));
 855         }
 856 
 857         builder.complete();
 858     }
 859 
 860     /**
 861      * Decodes the values of --add-reads, -add-exports, --add-opens or
 862      * --patch-modules options that are encoded in system properties.
 863      *
 864      * @param prefix the system property prefix
 865      * @praam regex the regex for splitting the RHS of the option value
 866      */
 867     private static Map<String, List<String>> decode(String prefix,
 868                                                     String regex,
 869                                                     boolean allowDuplicates) {
 870         int index = 0;
 871         // the system property is removed after decoding
 872         String value = getAndRemoveProperty(prefix + index);
 873         if (value == null)
 874             return Map.of();


 976 
 977     /*
 978      * Returns the command-line option name corresponds to the specified
 979      * system property prefix.
 980      */
 981     static String option(String prefix) {
 982         switch (prefix) {
 983             case "jdk.module.addexports.":
 984                 return ADD_EXPORTS;
 985             case "jdk.module.addopens.":
 986                 return ADD_OPENS;
 987             case "jdk.module.addreads.":
 988                 return ADD_READS;
 989             case "jdk.module.patch.":
 990                 return PATCH_MODULE;
 991             case "jdk.module.addmods.":
 992                 return ADD_MODULES;
 993             default:
 994                 throw new IllegalArgumentException(prefix);
 995         }
 996     }
 997 
 998     /**
 999      * Returns an iterator that yields all elements of the first iterator
1000      * followed by all the elements of the second iterator.
1001      */
1002     static <T> Iterator<T> concat(Iterator<T> iterator1, Iterator<T> iterator2) {
1003         return new Iterator<T>() {
1004             @Override
1005             public boolean hasNext() {
1006                 return iterator1.hasNext() || iterator2.hasNext();
1007             }
1008             @Override
1009             public T next() {
1010                 if (iterator1.hasNext()) return iterator1.next();
1011                 if (iterator2.hasNext()) return iterator2.next();
1012                 throw new NoSuchElementException();
1013             }
1014         };
1015     }
1016 
1017     /**
1018      * Wraps a (potentially not thread safe) ModuleFinder created during startup
1019      * for use after startup.
1020      */
1021     static class SafeModuleFinder implements ModuleFinder {
1022         private final Set<ModuleReference> mrefs;
1023         private volatile Map<String, ModuleReference> nameToModule;
1024 
1025         SafeModuleFinder(ModuleFinder finder) {
1026             this.mrefs = Collections.unmodifiableSet(finder.findAll());
1027         }
1028         @Override
1029         public Optional<ModuleReference> find(String name) {
1030             Objects.requireNonNull(name);
1031             Map<String, ModuleReference> nameToModule = this.nameToModule;
1032             if (nameToModule == null) {
1033                 this.nameToModule = nameToModule = mrefs.stream()
1034                         .collect(Collectors.toMap(m -> m.descriptor().name(),




 783                     break;
 784                 case "debug":
 785                     mode = IllegalAccessLogger.Mode.DEBUG;
 786                     break;
 787                 default:
 788                     fail("Value specified to --illegal-access not recognized:"
 789                             + " '" + value + "'");
 790                     return;
 791             }
 792         }
 793         IllegalAccessLogger.Builder builder
 794             = new IllegalAccessLogger.Builder(mode, System.err);
 795 
 796         if (concealedPackagesToOpen.isEmpty() && exportedPackagesToOpen.isEmpty()) {
 797             // need to generate (exploded build)
 798             IllegalAccessMaps maps = IllegalAccessMaps.generate(limitedFinder());
 799             concealedPackagesToOpen = maps.concealedPackagesToOpen();
 800             exportedPackagesToOpen = maps.exportedPackagesToOpen();
 801         }
 802 
 803         Set<String> emptySet = Set.of();
 804 
 805         // open specific packages in the system modules
 806         for (Module m : bootLayer.modules()) {
 807             ModuleDescriptor descriptor = m.getDescriptor();
 808             String name = m.getName();
 809 
 810             // skip open modules
 811             if (descriptor.isOpen()) {
 812                 continue;
 813             }
 814 
 815             // skip modules loaded from the upgrade module path
 816             if (upgradeModulePath != null
 817                 && upgradeModulePath.find(name).isPresent()) {
 818                 continue;
 819             }
 820 
 821             Set<String> concealedPackages = concealedPackagesToOpen.getOrDefault(name, emptySet);
 822             Set<String> exportedPackages = exportedPackagesToOpen.getOrDefault(name, emptySet);
 823 
 824             // refresh the set of concealed and exported packages if needed
 825             if (extraExportsOrOpens) {
 826                 concealedPackages = new HashSet<>(concealedPackages);
 827                 exportedPackages = new HashSet<>(exportedPackages);
 828                 Iterator<String> iterator = concealedPackages.iterator();
 829                 while (iterator.hasNext()) {
 830                     String pn = iterator.next();
 831                     if (m.isExported(pn, BootLoader.getUnnamedModule())) {
 832                         // concealed package is exported to ALL-UNNAMED
 833                         iterator.remove();
 834                         exportedPackages.add(pn);
 835                     }
 836                 }
 837                 iterator = exportedPackages.iterator();
 838                 while (iterator.hasNext()) {
 839                     String pn = iterator.next();
 840                     if (m.isOpen(pn, BootLoader.getUnnamedModule())) {
 841                         // exported package is opened to ALL-UNNAMED
 842                         iterator.remove();
 843                     }
 844                 }
 845             }
 846 
 847             // log reflective access to all types in concealed packages
 848             builder.logAccessToConcealedPackages(m, concealedPackages);
 849 
 850             // log reflective access to non-public members/types in exported packages
 851             builder.logAccessToExportedPackages(m, exportedPackages);
 852 
 853             // open the packages to unnamed modules
 854             JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
 855             jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);

 856         }
 857 
 858         builder.complete();
 859     }
 860 
 861     /**
 862      * Decodes the values of --add-reads, -add-exports, --add-opens or
 863      * --patch-modules options that are encoded in system properties.
 864      *
 865      * @param prefix the system property prefix
 866      * @praam regex the regex for splitting the RHS of the option value
 867      */
 868     private static Map<String, List<String>> decode(String prefix,
 869                                                     String regex,
 870                                                     boolean allowDuplicates) {
 871         int index = 0;
 872         // the system property is removed after decoding
 873         String value = getAndRemoveProperty(prefix + index);
 874         if (value == null)
 875             return Map.of();


 977 
 978     /*
 979      * Returns the command-line option name corresponds to the specified
 980      * system property prefix.
 981      */
 982     static String option(String prefix) {
 983         switch (prefix) {
 984             case "jdk.module.addexports.":
 985                 return ADD_EXPORTS;
 986             case "jdk.module.addopens.":
 987                 return ADD_OPENS;
 988             case "jdk.module.addreads.":
 989                 return ADD_READS;
 990             case "jdk.module.patch.":
 991                 return PATCH_MODULE;
 992             case "jdk.module.addmods.":
 993                 return ADD_MODULES;
 994             default:
 995                 throw new IllegalArgumentException(prefix);
 996         }



















 997     }
 998 
 999     /**
1000      * Wraps a (potentially not thread safe) ModuleFinder created during startup
1001      * for use after startup.
1002      */
1003     static class SafeModuleFinder implements ModuleFinder {
1004         private final Set<ModuleReference> mrefs;
1005         private volatile Map<String, ModuleReference> nameToModule;
1006 
1007         SafeModuleFinder(ModuleFinder finder) {
1008             this.mrefs = Collections.unmodifiableSet(finder.findAll());
1009         }
1010         @Override
1011         public Optional<ModuleReference> find(String name) {
1012             Objects.requireNonNull(name);
1013             Map<String, ModuleReference> nameToModule = this.nameToModule;
1014             if (nameToModule == null) {
1015                 this.nameToModule = nameToModule = mrefs.stream()
1016                         .collect(Collectors.toMap(m -> m.descriptor().name(),


< prev index next >