< prev index next >

test/jdk/modules/etc/JdkQualifiedExportTest.java

Print this page




  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8176537
  27  * @summary Check JDK modules have no qualified export to any upgradeable module
  28  * @modules java.base/jdk.internal.module
  29  * @run main JdkQualifiedExportTest
  30  */
  31 
  32 import jdk.internal.module.ModuleHashes;
  33 import jdk.internal.module.ModuleInfo;
  34 
  35 import java.io.IOException;
  36 import java.io.InputStream;
  37 import java.io.UncheckedIOException;

  38 import java.lang.module.ModuleDescriptor;
  39 import java.lang.module.ModuleDescriptor.Exports;
  40 import java.lang.module.ModuleDescriptor.Opens;
  41 import java.lang.module.ModuleFinder;
  42 import java.lang.module.ModuleReference;
  43 import java.util.Collections;
  44 import java.util.Comparator;
  45 import java.util.HashMap;
  46 import java.util.HashSet;
  47 import java.util.Map;
  48 import java.util.Set;
  49 
  50 public class JdkQualifiedExportTest {
  51     public static void main(String... args) {
  52         // check all system modules
  53         ModuleFinder.ofSystem().findAll()
  54                     .stream()
  55                     .map(ModuleReference::descriptor)
  56                     .sorted(Comparator.comparing(ModuleDescriptor::name))
  57                     .forEach(JdkQualifiedExportTest::check);
  58     }
  59 
  60     static void check(ModuleDescriptor md) {
  61         // skip checking if this is an upgradeable module
  62         if (!HashedModules.contains(md.name())) {
  63             return;
  64         }
  65 
  66         checkExports(md);
  67         checkOpens(md);
  68     }
  69 
  70     static Set<String> KNOWN_EXCEPTIONS =
  71         Set.of("java.xml/com.sun.xml.internal.stream.writers",

  72                "jdk.jsobject/jdk.internal.netscape.javascript.spi");
  73     static Set<String> DEPLOY_MODULES =
  74         Set.of("jdk.deploy", "jdk.plugin", "jdk.javaws");
  75 
  76     static void checkExports(ModuleDescriptor md) {
  77         // build a map of upgradeable module to Exports that are qualified to it
  78         // skip the qualified exports
  79         Map<String, Set<Exports>> targetToExports = new HashMap<>();
  80         md.exports().stream()
  81           .filter(Exports::isQualified)
  82           .forEach(e -> e.targets().stream()
  83                          .filter(mn -> !HashedModules.contains(mn) &&
  84                                            ModuleFinder.ofSystem().find(mn).isPresent())
  85                          .forEach(t -> targetToExports.computeIfAbsent(t, _k -> new HashSet<>())
  86                                                       .add(e)));
  87 
  88         if (targetToExports.size() > 0) {
  89             String mn = md.name();
  90 
  91             System.err.println(mn);
  92             targetToExports.entrySet().stream()
  93                 .sorted(Map.Entry.comparingByKey())
  94                 .forEach(e -> {
  95                     e.getValue().stream()
  96                      .forEach(exp -> System.err.format("    exports %s to %s%n",
  97                                                        exp.source(), e.getKey()));
  98                 });
  99 
 100             // workaround until all qualified exports to upgradeable modules
 101             // are eliminated
 102             if (targetToExports.entrySet().stream()
 103                     .filter(e -> !DEPLOY_MODULES.contains(e.getKey()))
 104                     .flatMap(e -> e.getValue().stream())
 105                     .anyMatch(e -> !KNOWN_EXCEPTIONS.contains(mn + "/" + e.source()))) {
 106                 throw new RuntimeException(mn + " can't export package to upgradeable modules");
 107             }
 108         }
 109     }
 110 
 111     static void checkOpens(ModuleDescriptor md) {
 112         // build a map of upgradeable module to Exports that are qualified to it
 113         // skip the qualified exports
 114         Map<String, Set<Opens>> targetToOpens = new HashMap<>();
 115         md.opens().stream()
 116             .filter(Opens::isQualified)
 117             .forEach(e -> e.targets().stream()
 118                            .filter(mn -> !HashedModules.contains(mn) &&
 119                                             ModuleFinder.ofSystem().find(mn).isPresent())
 120                            .forEach(t -> targetToOpens.computeIfAbsent(t, _k -> new HashSet<>())
 121                                                       .add(e)));
 122 
 123         if (targetToOpens.size() > 0) {
 124             String mn = md.name();
 125 
 126             System.err.println(mn);
 127             targetToOpens.entrySet().stream()
 128                 .sorted(Map.Entry.comparingByKey())
 129                 .forEach(e -> {
 130                     e.getValue().stream()
 131                      .forEach(exp -> System.err.format("    opens %s to %s%n",
 132                                                        exp.source(), e.getKey()));
 133                 });
 134 
 135             throw new RuntimeException(mn + " can't open package to upgradeable modules");
 136         }
 137     }
 138 

















 139     private static class HashedModules {
 140         static Set<String> HASHED_MODULES = hashedModules();
 141 
 142         static Set<String> hashedModules() {
 143             Module javaBase = Object.class.getModule();
 144             try (InputStream in = javaBase.getResourceAsStream("module-info.class")) {
 145                 ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
 146                 ModuleHashes hashes = attrs.recordedHashes();
 147                 if (hashes == null)
 148                     return Collections.emptySet();
 149 
 150                 Set<String> names = new HashSet<>(hashes.names());
 151                 names.add(javaBase.getName());
 152                 return names;
 153             } catch (IOException e) {
 154                 throw new UncheckedIOException(e);
 155             }
 156         }
 157 
 158         /*


  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @bug 8176537
  27  * @summary Check JDK modules have no qualified export to any upgradeable module
  28  * @modules java.base/jdk.internal.module
  29  * @run main JdkQualifiedExportTest
  30  */
  31 
  32 import jdk.internal.module.ModuleHashes;
  33 import jdk.internal.module.ModuleInfo;
  34 
  35 import java.io.IOException;
  36 import java.io.InputStream;
  37 import java.io.UncheckedIOException;
  38 import java.lang.module.Configuration;
  39 import java.lang.module.ModuleDescriptor;
  40 import java.lang.module.ModuleDescriptor.Exports;
  41 import java.lang.module.ModuleDescriptor.Opens;
  42 import java.lang.module.ModuleFinder;
  43 import java.lang.module.ModuleReference;
  44 import java.util.Collections;
  45 import java.util.Comparator;
  46 import java.util.HashMap;
  47 import java.util.HashSet;
  48 import java.util.Map;
  49 import java.util.Set;
  50 
  51 public class JdkQualifiedExportTest {
  52     public static void main(String... args) {
  53         // check all system modules
  54         ModuleFinder.ofSystem().findAll()
  55                     .stream()
  56                     .map(ModuleReference::descriptor)
  57                     .sorted(Comparator.comparing(ModuleDescriptor::name))
  58                     .forEach(JdkQualifiedExportTest::check);
  59     }
  60 
  61     static void check(ModuleDescriptor md) {
  62         // skip checking if this is an upgradeable module
  63         if (!HashedModules.contains(md.name())) {
  64             return;
  65         }
  66 
  67         checkExports(md);
  68         checkOpens(md);
  69     }
  70 
  71     static Set<String> KNOWN_EXCEPTIONS =
  72         Set.of("java.xml/com.sun.xml.internal.stream.writers",
  73                "jdk.internal.vm.ci/jdk.vm.ci.services",
  74                "jdk.jsobject/jdk.internal.netscape.javascript.spi");


  75 
  76     static void checkExports(ModuleDescriptor md) {
  77         // build a map of upgradeable module to Exports that are qualified to it
  78         // skip the qualified exports
  79         Map<String, Set<Exports>> targetToExports = new HashMap<>();
  80         md.exports().stream()
  81           .filter(Exports::isQualified)
  82           .forEach(e -> e.targets().stream()
  83                          .filter(mn -> accept(md, mn))

  84                          .forEach(t -> targetToExports.computeIfAbsent(t, _k -> new HashSet<>())
  85                                                       .add(e)));
  86 
  87         if (targetToExports.size() > 0) {
  88             String mn = md.name();
  89 
  90             System.err.println(mn);
  91             targetToExports.entrySet().stream()
  92                 .sorted(Map.Entry.comparingByKey())
  93                 .forEach(e -> {
  94                     e.getValue().stream()
  95                      .forEach(exp -> System.err.format("    exports %s to %s%n",
  96                                                        exp.source(), e.getKey()));
  97                 });
  98 
  99             // no qualified exports to upgradeable modules are expected
 100             // except the known exception cases
 101             if (targetToExports.entrySet().stream()

 102                     .flatMap(e -> e.getValue().stream())
 103                     .anyMatch(e -> !KNOWN_EXCEPTIONS.contains(mn + "/" + e.source()))) {
 104                 throw new RuntimeException(mn + " can't export package to upgradeable modules");
 105             }
 106         }
 107     }
 108 
 109     static void checkOpens(ModuleDescriptor md) {
 110         // build a map of upgradeable module to Exports that are qualified to it
 111         // skip the qualified exports
 112         Map<String, Set<Opens>> targetToOpens = new HashMap<>();
 113         md.opens().stream()
 114             .filter(Opens::isQualified)
 115             .forEach(e -> e.targets().stream()
 116                            .filter(mn -> accept(md, mn))

 117                            .forEach(t -> targetToOpens.computeIfAbsent(t, _k -> new HashSet<>())
 118                                                       .add(e)));
 119 
 120         if (targetToOpens.size() > 0) {
 121             String mn = md.name();
 122 
 123             System.err.println(mn);
 124             targetToOpens.entrySet().stream()
 125                 .sorted(Map.Entry.comparingByKey())
 126                 .forEach(e -> {
 127                     e.getValue().stream()
 128                      .forEach(exp -> System.err.format("    opens %s to %s%n",
 129                                                        exp.source(), e.getKey()));
 130                 });
 131 
 132             throw new RuntimeException(mn + " can't open package to upgradeable modules");
 133         }
 134     }
 135 
 136     /**
 137      * Returns true if target is an upgradeable module but not required
 138      * by the source module directly and indirectly.
 139      */
 140     private static boolean accept(ModuleDescriptor source, String target) {
 141         if (HashedModules.contains(target))
 142             return false;
 143 
 144         if (!ModuleFinder.ofSystem().find(target).isPresent())
 145             return false;
 146 
 147         Configuration cf = Configuration.empty().resolve(ModuleFinder.of(),
 148                                                          ModuleFinder.ofSystem(),
 149                                                          Set.of(source.name()));
 150         return cf.findModule(target).orElse(null) == null;
 151     }
 152 
 153     private static class HashedModules {
 154         static Set<String> HASHED_MODULES = hashedModules();
 155 
 156         static Set<String> hashedModules() {
 157             Module javaBase = Object.class.getModule();
 158             try (InputStream in = javaBase.getResourceAsStream("module-info.class")) {
 159                 ModuleInfo.Attributes attrs = ModuleInfo.read(in, null);
 160                 ModuleHashes hashes = attrs.recordedHashes();
 161                 if (hashes == null)
 162                     return Collections.emptySet();
 163 
 164                 Set<String> names = new HashSet<>(hashes.names());
 165                 names.add(javaBase.getName());
 166                 return names;
 167             } catch (IOException e) {
 168                 throw new UncheckedIOException(e);
 169             }
 170         }
 171 
 172         /*
< prev index next >