src/java.base/share/classes/jdk/internal/module/DefaultRoots.java
changeset 50738 6cc2dc161c64
parent 47216 71c04702a3d5
--- a/src/java.base/share/classes/jdk/internal/module/DefaultRoots.java	Fri Jun 22 17:49:21 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/module/DefaultRoots.java	Sat Jun 23 08:03:52 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,14 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 package jdk.internal.module;
 
 import java.lang.module.ModuleDescriptor;
 import java.lang.module.ModuleFinder;
 import java.lang.module.ModuleReference;
-import java.util.HashSet;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Defines methods to compute the default set of root modules for the unnamed
@@ -36,58 +37,45 @@
  */
 
 public final class DefaultRoots {
-    private static final String JAVA_SE = "java.se";
-
     private DefaultRoots() { }
 
     /**
-     * Returns the default set of root modules for the unnamed module computed from
-     * the system modules observable with the given module finder.
+     * Returns the default set of root modules for the unnamed module from the
+     * modules observable with the intersection of two module finders.
+     *
+     * The first module finder should be the module finder that finds modules on
+     * the upgrade module path or among the system modules. The second module
+     * finder should be the module finder that finds all modules on the module
+     * path, or a subset of when using --limit-modules.
      */
-    static Set<String> compute(ModuleFinder systemModuleFinder, ModuleFinder finder) {
-        Set<String> roots = new HashSet<>();
-
-        boolean hasJava = false;
-        if (systemModuleFinder.find(JAVA_SE).isPresent()) {
-            if (finder == systemModuleFinder || finder.find(JAVA_SE).isPresent()) {
-                // java.se is a system module
-                hasJava = true;
-                roots.add(JAVA_SE);
-            }
-        }
-
-        for (ModuleReference mref : systemModuleFinder.findAll()) {
-            String mn = mref.descriptor().name();
-            if (hasJava && mn.startsWith("java.")) {
-                // not a root
-                continue;
-            }
-
-            if (ModuleResolution.doNotResolveByDefault(mref)) {
-                // not a root
-                continue;
-            }
-
-            if ((finder == systemModuleFinder || finder.find(mn).isPresent())) {
-                // add as root if exports at least one package to all modules
-                ModuleDescriptor descriptor = mref.descriptor();
-                for (ModuleDescriptor.Exports e : descriptor.exports()) {
-                    if (!e.isQualified()) {
-                        roots.add(mn);
-                        break;
-                    }
-                }
-            }
-        }
-
-        return roots;
+    static Set<String> compute(ModuleFinder finder1, ModuleFinder finder2) {
+        return finder1.findAll().stream()
+                .filter(mref -> !ModuleResolution.doNotResolveByDefault(mref))
+                .map(ModuleReference::descriptor)
+                .filter(descriptor -> finder2.find(descriptor.name()).isPresent()
+                                      && exportsAPI(descriptor))
+                .map(ModuleDescriptor::name)
+                .collect(Collectors.toSet());
     }
 
     /**
      * Returns the default set of root modules for the unnamed module from the
      * modules observable with the given module finder.
+     *
+     * This method is used by the jlink system modules plugin.
      */
     public static Set<String> compute(ModuleFinder finder) {
         return compute(finder, finder);
     }
+
+    /**
+     * Returns true if the given module exports a package to all modules
+     */
+    private static boolean exportsAPI(ModuleDescriptor descriptor) {
+        return descriptor.exports()
+                .stream()
+                .filter(e -> !e.isQualified())
+                .findAny()
+                .isPresent();
+    }
 }