Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8345573: Module dependencies not resolved from run-time image when --limit-module is being used #22609

Closed
77 changes: 28 additions & 49 deletions src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java
Original file line number Diff line number Diff line change
@@ -377,28 +377,41 @@ public static void createImage(JlinkConfiguration config,
// the token for "all modules on the module path"
private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
private JlinkConfiguration initJlinkConfig() throws BadArgs {
ModuleFinder initialFinder = createFinderFromPath(options.modulePath);
boolean isLinkFromRuntime = determineLinkFromRuntime(initialFinder, options.modulePath);
ModuleFinder rootsFinder = isLinkFromRuntime ? ModuleFinder.compose(ModuleFinder.ofSystem(),
initialFinder) :
initialFinder;
if (rootsFinder.find("java.base").isEmpty()) {
assert !isLinkFromRuntime : "Expected regular JMODs based link";
// External module linked into a custom runtime, but JDK modules
// not observable on the module path. Add the default module path
// if that exists.
ModuleFinder appModulePathFinder = createFinderFromPath(options.modulePath);
ModuleFinder finder = appModulePathFinder;
boolean isLinkFromRuntime = false;
if (!appModulePathFinder.find("java.base").isPresent()) {
// If the application module path finder doesn't contain the
// java.base module we have one of two cases:
// 1. A custom module is being linked into a runtime, but the JDK
// modules have not been provided on the module path.
// 2. We have a run-time image based link.
//
// Distinguish case 2 by adding the default 'jmods' folder and try
// the look-up again. For case 1 this will now find java.base, but
// not for case 2, since the jmods folder is not there or doesn't
// include the java.base module.
Path defModPath = getDefaultModulePath();
if (defModPath != null) {
options.modulePath.add(defModPath);
rootsFinder = createFinderFromPath(options.modulePath);
finder = createFinderFromPath(options.modulePath);
}
// We've just added the default module path ('jmods'). If we still
// don't find java.base, we must resolve JDK modules from the
// current run-time image.
if (!finder.find("java.base").isPresent()) {
isLinkFromRuntime = true;
// JDK modules come from the system module path
finder = ModuleFinder.compose(ModuleFinder.ofSystem(), appModulePathFinder);
}
}

// Determine the roots set
Set<String> roots = new HashSet<>();
for (String mod : options.addMods) {
if (mod.equals(ALL_MODULE_PATH) && options.modulePath.size() > 0) {
ModuleFinder mf = newModuleFinder(rootsFinder, options.limitMods, Set.of(), isLinkFromRuntime);
// all observable modules are roots
if (mod.equals(ALL_MODULE_PATH)) {
ModuleFinder mf = newModuleFinder(finder, options.limitMods,
Set.of(), isLinkFromRuntime);
mf.findAll()
.stream()
.map(ModuleReference::descriptor)
@@ -408,8 +421,7 @@ private JlinkConfiguration initJlinkConfig() throws BadArgs {
roots.add(mod);
}
}

ModuleFinder finder = newModuleFinder(rootsFinder, options.limitMods, roots, isLinkFromRuntime);
finder = newModuleFinder(finder, options.limitMods, roots, isLinkFromRuntime);

// --keep-packaged-modules doesn't make sense as we are not linking
// from packaged modules to begin with.
@@ -425,39 +437,6 @@ private JlinkConfiguration initJlinkConfig() throws BadArgs {
options.generateLinkableRuntime);
}

/*
* Determine whether or not JDK modules should be resolved from the run-time
* image.
*
* @return {@code false} if JMODs including java.base are present on the
* module path or in the default module path ('jmods'). {@code true}
* otherwise.
*/
private static boolean determineLinkFromRuntime(ModuleFinder initialFinder,
List<Path> modulePath) {
boolean linkFromRuntime = false;
if (!initialFinder.find("java.base").isPresent()) {
// If the initial finder doesn't contain the java.base module
// we have one of two cases:
// 1. A custom module is being linked into a runtime, but the JDK
// modules have not been provided.
// 2. We have a run-time image based link.
//
// Distinguish case 2 by adding the default 'jmods' folder and try
// the look-up again. For case 1 this will now find java.base, but
// not for case 2, since the jmods folder is not there or doesn't
// include the java.base module.
List<Path> pathCopy = new ArrayList<>(modulePath);
Path defaultPath = getDefaultModulePath();
if (defaultPath != null) {
pathCopy.add(defaultPath);
}
ModuleFinder finder = createFinderFromPath(pathCopy);
linkFromRuntime = !finder.find("java.base").isPresent();
}
return linkFromRuntime;
}

/*
* Creates a ModuleFinder for the given module paths.
*/