# HG changeset patch # User herrick # Date 1548894322 18000 # Node ID 8041f62342f0f7e9aa5240c92156d9d8ade8869c # Parent 846d4865b362ec72d6ec779e3281630c18f65b94 8217792 : Investigate what modules are included Reviewed-by: kcr, almatvee diff -r 846d4865b362 -r 8041f62342f0 src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java Wed Jan 30 10:42:19 2019 -0500 +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/JLinkBundlerHelper.java Wed Jan 30 19:25:22 2019 -0500 @@ -45,6 +45,11 @@ import java.util.ResourceBundle; import java.util.Set; import java.util.Optional; +import java.util.Arrays; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.lang.module.Configuration; +import java.lang.module.ResolvedModule; import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReference; @@ -182,7 +187,7 @@ Path javaBasePath = findPathOfModule(modulePath, "java.base.jmod"); Set addModules = getValidModules(modulePath, StandardBundlerParam.ADD_MODULES.fetchFrom(params), - limitModules, true); + limitModules); if (javaBasePath != null && javaBasePath.toFile().exists()) { @@ -230,10 +235,9 @@ } private static Set getValidModules(List modulePath, - Set addModules, Set limitModules, - boolean forJRE) { + Set addModules, Set limitModules) { ModuleHelper moduleHelper = new ModuleHelper( - modulePath, addModules, limitModules, forJRE); + modulePath, addModules, limitModules); return removeInvalidModules(modulePath, moduleHelper.modules()); } @@ -262,17 +266,16 @@ // Modules - // The default for an unnamed jar is ALL_DEFAULT with the - // non-valid modules removed. if (mainJarType == ModFile.ModType.UnnamedJar) { - addModules.add(ModuleHelper.ALL_RUNTIME); + // The default for an unnamed jar is ALL_DEFAULT + addModules.add(ModuleHelper.ALL_DEFAULT); } else if (mainJarType == ModFile.ModType.Unknown || mainJarType == ModFile.ModType.ModularJar) { String mainModule = getMainModule(params); addModules.add(mainModule); } addModules.addAll(getValidModules( - modulePath, addModules, limitModules, false)); + modulePath, addModules, limitModules)); Log.verbose(MessageFormat.format( I18N.getString("message.modules"), addModules.toString())); @@ -302,9 +305,9 @@ boolean stripNativeCommands = StandardBundlerParam.STRIP_NATIVE_COMMANDS.fetchFrom(params); Path outputDir = imageBuilder.getRoot(); - addModules.add(ModuleHelper.ALL_RUNTIME); + addModules.add(ModuleHelper.ALL_MODULE_PATH); Set redistModules = getValidModules(modulePath, - addModules, limitModules, true); + addModules, limitModules); addModules.addAll(redistModules); Log.verbose(MessageFormat.format( @@ -340,6 +343,51 @@ return result; } + /* + * Returns the set of modules that would be visible by default for + * a non-modular-aware application consisting of the given elements. + */ + private static Set getDefaultModules( + Path[] paths, String[] addModules) { + + // the modules in the run-time image that export an API + Stream systemRoots = ModuleFinder.ofSystem().findAll().stream() + .map(ModuleReference::descriptor) + .filter(descriptor -> exportsAPI(descriptor)) + .map(ModuleDescriptor::name); + + Set roots; + if (addModules == null || addModules.length == 0) { + roots = systemRoots.collect(Collectors.toSet()); + } else { + var extraRoots = Stream.of(addModules); + roots = Stream.concat(systemRoots, + extraRoots).collect(Collectors.toSet()); + } + + ModuleFinder finder = ModuleFinder.ofSystem(); + if (paths != null && paths.length > 0) { + finder = ModuleFinder.compose(finder, ModuleFinder.of(paths)); + } + return Configuration.empty() + .resolveAndBind(finder, ModuleFinder.of(), roots) + .modules() + .stream() + .map(ResolvedModule::name) + .collect(Collectors.toSet()); + } + + /* + * Returns true if the given module exports an API to all module. + */ + private static boolean exportsAPI(ModuleDescriptor descriptor) { + return descriptor.exports() + .stream() + .filter(e -> !e.isQualified()) + .findAny() + .isPresent(); + } + private static Set removeInvalidModules( List modulePath, Set modules) { Set result = new LinkedHashSet(); @@ -398,48 +446,40 @@ private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH"; // The token for "all valid runtime modules". - static final String ALL_RUNTIME = "ALL-RUNTIME"; + static final String ALL_DEFAULT = "ALL-DEFAULT"; private final Set modules = new HashSet<>(); private enum Macros {None, AllModulePath, AllRuntime} - ModuleHelper(List paths, Set roots, - Set limitMods, boolean forJRE) { - Macros macro = Macros.None; - - for (Iterator iterator = roots.iterator(); + ModuleHelper(List paths, Set addModules, + Set limitModules) { + boolean addAllModulePath = false; + boolean addDefaultMods = false; + + for (Iterator iterator = addModules.iterator(); iterator.hasNext();) { String module = iterator.next(); switch (module) { case ALL_MODULE_PATH: iterator.remove(); - macro = Macros.AllModulePath; + addAllModulePath = true; break; - case ALL_RUNTIME: + case ALL_DEFAULT: iterator.remove(); - macro = Macros.AllRuntime; + addDefaultMods = true; break; default: this.modules.add(module); } } - switch (macro) { - case AllModulePath: - this.modules.addAll(getModuleNamesFromPath(paths)); - break; - case AllRuntime: - Set runtimeModules = - ModuleLayer.boot().modules(); - for (Module m : runtimeModules) { - String name = m.getName(); - if (forJRE && isModuleExcludedFromJRE(name)) { - continue; // JRE does not include this module - } - this.modules.add(name); - } - break; + if (addAllModulePath) { + this.modules.addAll(getModuleNamesFromPath(paths)); + } else if (addDefaultMods) { + this.modules.addAll(getDefaultModules( + paths.toArray(new Path[0]), + addModules.toArray(new String[0]))); } } @@ -447,24 +487,18 @@ return modules; } - private boolean isModuleExcludedFromJRE(String name) { - return false; // not excluding any modules from JRE at this time - } + private static Set getModuleNamesFromPath(List Value) { + Set result = new LinkedHashSet(); + ModuleManager mm = new ModuleManager(Value); + List modFiles = mm.getModules( + EnumSet.of(ModuleManager.SearchType.ModularJar, + ModuleManager.SearchType.Jmod, + ModuleManager.SearchType.ExplodedModule)); - private static Set getModuleNamesFromPath(List Value) { - Set result = new LinkedHashSet(); - ModuleManager mm = new ModuleManager(Value); - List modFiles = - mm.getModules( - EnumSet.of(ModuleManager.SearchType.ModularJar, - ModuleManager.SearchType.Jmod, - ModuleManager.SearchType.ExplodedModule)); - - for (ModFile modFile : modFiles) { - result.add(modFile.getModName()); - } - - return result; + for (ModFile modFile : modFiles) { + result.add(modFile.getModName()); + } + return result; } } }