8189777: jlink --module-path default value and automatic addition of $JAVA_HOME/jmods if java.base is missing
Reviewed-by: alanb, mchung
This commit is contained in:
parent
b905e51da7
commit
f8b8a16f4b
@ -27,7 +27,9 @@ package jdk.tools.jlink.internal;
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -146,10 +148,8 @@ public final class Jlink {
|
||||
*/
|
||||
public static final class JlinkConfiguration {
|
||||
|
||||
private final List<Path> modulepaths;
|
||||
private final Path output;
|
||||
private final Set<String> modules;
|
||||
private final Set<String> limitmods;
|
||||
private final ByteOrder endian;
|
||||
private final ModuleFinder finder;
|
||||
|
||||
@ -157,33 +157,18 @@ public final class Jlink {
|
||||
* jlink configuration,
|
||||
*
|
||||
* @param output Output directory, must not exist.
|
||||
* @param modulepaths Modules paths
|
||||
* @param modules The possibly-empty set of root modules to resolve
|
||||
* @param limitmods Limit the universe of observable modules
|
||||
* @param endian Jimage byte order. Native order by default
|
||||
* @param finder the ModuleFinder for this configuration
|
||||
*/
|
||||
public JlinkConfiguration(Path output,
|
||||
List<Path> modulepaths,
|
||||
Set<String> modules,
|
||||
Set<String> limitmods,
|
||||
ByteOrder endian) {
|
||||
if (Objects.requireNonNull(modulepaths).isEmpty()) {
|
||||
throw new IllegalArgumentException("Empty module path");
|
||||
}
|
||||
|
||||
ByteOrder endian,
|
||||
ModuleFinder finder) {
|
||||
this.output = output;
|
||||
this.modulepaths = modulepaths;
|
||||
this.modules = Objects.requireNonNull(modules);
|
||||
this.limitmods = Objects.requireNonNull(limitmods);
|
||||
this.endian = Objects.requireNonNull(endian);
|
||||
this.finder = moduleFinder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the modulepaths
|
||||
*/
|
||||
public List<Path> getModulepaths() {
|
||||
return modulepaths;
|
||||
this.finder = finder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,13 +192,6 @@ public final class Jlink {
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the limitmods
|
||||
*/
|
||||
public Set<String> getLimitmods() {
|
||||
return limitmods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link ModuleFinder} that finds all observable modules
|
||||
* for this jlink configuration.
|
||||
@ -244,37 +222,16 @@ public final class Jlink {
|
||||
modules);
|
||||
}
|
||||
|
||||
private ModuleFinder moduleFinder() {
|
||||
Path[] entries = modulepaths.toArray(new Path[0]);
|
||||
ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
|
||||
if (!limitmods.isEmpty()) {
|
||||
finder = JlinkTask.limitFinder(finder, limitmods, modules);
|
||||
}
|
||||
return finder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("output=").append(output).append("\n");
|
||||
StringBuilder pathsBuilder = new StringBuilder();
|
||||
for (Path p : modulepaths) {
|
||||
pathsBuilder.append(p).append(",");
|
||||
}
|
||||
builder.append("modulepaths=").append(pathsBuilder).append("\n");
|
||||
|
||||
StringBuilder modsBuilder = new StringBuilder();
|
||||
for (String p : modules) {
|
||||
modsBuilder.append(p).append(",");
|
||||
}
|
||||
builder.append("modules=").append(modsBuilder).append("\n");
|
||||
|
||||
StringBuilder limitsBuilder = new StringBuilder();
|
||||
for (String p : limitmods) {
|
||||
limitsBuilder.append(p).append(",");
|
||||
}
|
||||
builder.append("limitmodules=").append(limitsBuilder).append("\n");
|
||||
builder.append("endian=").append(endian).append("\n");
|
||||
return builder.toString();
|
||||
}
|
||||
|
@ -251,9 +251,18 @@ public class JlinkTask {
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
|
||||
if (options.modulePath.isEmpty()) {
|
||||
throw taskHelper.newBadArgs("err.modulepath.must.be.specified")
|
||||
.showUsage(true);
|
||||
// no --module-path specified - try to set $JAVA_HOME/jmods if that exists
|
||||
Path jmods = getDefaultModulePath();
|
||||
if (jmods != null) {
|
||||
options.modulePath.add(jmods);
|
||||
}
|
||||
|
||||
if (options.modulePath.isEmpty()) {
|
||||
throw taskHelper.newBadArgs("err.modulepath.must.be.specified")
|
||||
.showUsage(true);
|
||||
}
|
||||
}
|
||||
|
||||
JlinkConfiguration config = initJlinkConfig();
|
||||
@ -347,14 +356,7 @@ public class JlinkTask {
|
||||
Set<String> roots = new HashSet<>();
|
||||
for (String mod : options.addMods) {
|
||||
if (mod.equals(ALL_MODULE_PATH)) {
|
||||
Path[] entries = options.modulePath.toArray(new Path[0]);
|
||||
ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
|
||||
if (!options.limitMods.isEmpty()) {
|
||||
// finder for the observable modules specified in
|
||||
// the --module-path and --limit-modules options
|
||||
finder = limitFinder(finder, options.limitMods, Collections.emptySet());
|
||||
}
|
||||
|
||||
ModuleFinder finder = newModuleFinder(options.modulePath, options.limitMods, Set.of());
|
||||
// all observable modules are roots
|
||||
finder.findAll()
|
||||
.stream()
|
||||
@ -366,11 +368,19 @@ public class JlinkTask {
|
||||
}
|
||||
}
|
||||
|
||||
ModuleFinder finder = newModuleFinder(options.modulePath, options.limitMods, roots);
|
||||
if (!finder.find("java.base").isPresent()) {
|
||||
Path defModPath = getDefaultModulePath();
|
||||
if (defModPath != null) {
|
||||
options.modulePath.add(defModPath);
|
||||
}
|
||||
finder = newModuleFinder(options.modulePath, options.limitMods, roots);
|
||||
}
|
||||
|
||||
return new JlinkConfiguration(options.output,
|
||||
options.modulePath,
|
||||
roots,
|
||||
options.limitMods,
|
||||
options.endian);
|
||||
options.endian,
|
||||
finder);
|
||||
}
|
||||
|
||||
private void createImage(JlinkConfiguration config) throws Exception {
|
||||
@ -398,6 +408,14 @@ public class JlinkTask {
|
||||
stack.operate(imageProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the system module path or null
|
||||
*/
|
||||
public static Path getDefaultModulePath() {
|
||||
Path jmods = Paths.get(System.getProperty("java.home"), "jmods");
|
||||
return Files.isDirectory(jmods)? jmods : null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a module finder of the given module path that limits
|
||||
* the observable modules to those in the transitive closure of
|
||||
@ -408,12 +426,15 @@ public class JlinkTask {
|
||||
Set<String> limitMods,
|
||||
Set<String> roots)
|
||||
{
|
||||
if (Objects.requireNonNull(paths).isEmpty()) {
|
||||
throw new IllegalArgumentException("Empty module path");
|
||||
}
|
||||
Path[] entries = paths.toArray(new Path[0]);
|
||||
ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
|
||||
|
||||
// if limitmods is specified then limit the universe
|
||||
if (!limitMods.isEmpty()) {
|
||||
finder = limitFinder(finder, limitMods, roots);
|
||||
if (limitMods != null && !limitMods.isEmpty()) {
|
||||
finder = limitFinder(finder, limitMods, Objects.requireNonNull(roots));
|
||||
}
|
||||
return finder;
|
||||
}
|
||||
|
@ -96,10 +96,10 @@ public final class AppRuntimeImageBuilder {
|
||||
// jlink main arguments
|
||||
Jlink.JlinkConfiguration jlinkConfig =
|
||||
new Jlink.JlinkConfiguration(new File("").toPath(), // Unused
|
||||
modulePath,
|
||||
addModules,
|
||||
limitModules,
|
||||
ByteOrder.nativeOrder());
|
||||
ByteOrder.nativeOrder(),
|
||||
moduleFinder(modulePath,
|
||||
limitModules, addModules));
|
||||
|
||||
// plugin configuration
|
||||
List<Plugin> plugins = new ArrayList<Plugin>();
|
||||
|
@ -39,6 +39,7 @@ import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import jdk.tools.jlink.internal.Jlink;
|
||||
import jdk.tools.jlink.internal.JlinkTask;
|
||||
import jdk.tools.jlink.builder.DefaultImageBuilder;
|
||||
import jdk.tools.jlink.plugin.ResourcePool;
|
||||
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
|
||||
@ -159,7 +160,8 @@ public class IntegrationTest {
|
||||
Set<String> limits = new HashSet<>();
|
||||
limits.add("java.management");
|
||||
JlinkConfiguration config = new Jlink.JlinkConfiguration(output,
|
||||
modulePaths, mods, limits, ByteOrder.nativeOrder());
|
||||
mods, ByteOrder.nativeOrder(),
|
||||
JlinkTask.newModuleFinder(modulePaths, limits, mods));
|
||||
|
||||
List<Plugin> lst = new ArrayList<>();
|
||||
|
||||
|
@ -42,6 +42,7 @@ import tests.JImageGenerator;
|
||||
/*
|
||||
* @test
|
||||
* @summary Test image creation
|
||||
* @bug 8189777
|
||||
* @author Jean-Francois Denise
|
||||
* @library ../lib
|
||||
* @modules java.base/jdk.internal.jimage
|
||||
@ -105,6 +106,37 @@ public class JLinkTest {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// No --module-path specified. $JAVA_HOME/jmods should be assumed.
|
||||
// The following should succeed as it uses only system modules.
|
||||
String imageDir = "bug818977-no-modulepath";
|
||||
JImageGenerator.getJLinkTask()
|
||||
.output(helper.createNewImageDir(imageDir))
|
||||
.addMods("jdk.scripting.nashorn")
|
||||
.call().assertSuccess();
|
||||
}
|
||||
|
||||
{
|
||||
// invalid --module-path specified. java.base not found it it.
|
||||
// $JAVA_HOME/jmods should be added automatically.
|
||||
// The following should succeed as it uses only system modules.
|
||||
String imageDir = "bug8189777-invalid-modulepath";
|
||||
JImageGenerator.getJLinkTask()
|
||||
.modulePath("does_not_exist_path")
|
||||
.output(helper.createNewImageDir(imageDir))
|
||||
.addMods("jdk.scripting.nashorn")
|
||||
.call().assertSuccess();
|
||||
}
|
||||
|
||||
{
|
||||
// No --module-path specified. --add-modules ALL-MODULE-PATH specified.
|
||||
String imageDir = "bug8189777-all-module-path";
|
||||
JImageGenerator.getJLinkTask()
|
||||
.output(helper.createNewImageDir(imageDir))
|
||||
.addMods("ALL-MODULE-PATH")
|
||||
.call().assertSuccess();
|
||||
}
|
||||
|
||||
{
|
||||
String moduleName = "bug8134651";
|
||||
JImageGenerator.getJLinkTask()
|
||||
@ -122,6 +154,17 @@ public class JLinkTest {
|
||||
.output(helper.createNewImageDir(moduleName))
|
||||
.addMods("leaf1")
|
||||
.call().assertFailure("Error: no value given for --module-path");
|
||||
// do not include standard module path - should be added automatically
|
||||
JImageGenerator.getJLinkTask()
|
||||
.modulePath(helper.defaultModulePath(false))
|
||||
.output(helper.createNewImageDir(moduleName))
|
||||
.addMods("leaf1")
|
||||
.call().assertSuccess();
|
||||
// no --module-path. default sys mod path is assumed - but that won't contain 'leaf1' module
|
||||
JImageGenerator.getJLinkTask()
|
||||
.output(helper.createNewImageDir(moduleName))
|
||||
.addMods("leaf1")
|
||||
.call().assertFailure("Error: Module leaf1 not found");
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -136,7 +136,11 @@ public class Helper {
|
||||
}
|
||||
|
||||
public String defaultModulePath() {
|
||||
return stdjmods.toAbsolutePath().toString() + File.pathSeparator
|
||||
return defaultModulePath(true);
|
||||
}
|
||||
|
||||
public String defaultModulePath(boolean includeStdMods) {
|
||||
return (includeStdMods? stdjmods.toAbsolutePath().toString() : "") + File.pathSeparator
|
||||
+ jmods.toAbsolutePath().toString() + File.pathSeparator
|
||||
+ jars.toAbsolutePath().toString() + File.pathSeparator
|
||||
+ explodedmodsclasses.toAbsolutePath().toString();
|
||||
|
Loading…
Reference in New Issue
Block a user