diff --git a/sdk/mx.sdk/mx_sdk_vm_impl.py b/sdk/mx.sdk/mx_sdk_vm_impl.py index 0e4f50a61532..1a0908e0e6e5 100644 --- a/sdk/mx.sdk/mx_sdk_vm_impl.py +++ b/sdk/mx.sdk/mx_sdk_vm_impl.py @@ -2220,13 +2220,9 @@ def _get_extra_jvm_args(): extra_jvm_args = mx.list_to_cmd_line(image_config.extra_jvm_args) if not _jlink_libraries(): if mx.is_windows(): - extra_jvm_args = ' '.join([extra_jvm_args, r'--upgrade-module-path "%location%\..\..\jvmci\graal.jar"', - r'--add-modules org.graalvm.polyglot', - r'--module-path "%location%\..\..\truffle\truffle-api.jar:%location%\..\..\jvmci\polyglot.jar"']) + extra_jvm_args = ' '.join([extra_jvm_args, r'--upgrade-module-path "%location%\..\..\jvmci\graal.jar"']) else: - extra_jvm_args = ' '.join([extra_jvm_args, '--upgrade-module-path "${location}/../../jvmci/graal.jar"', - '--add-modules org.graalvm.polyglot', - '--module-path "${location}/../../truffle/truffle-api.jar:${location}/../../jvmci/polyglot.jar"']) + extra_jvm_args = ' '.join([extra_jvm_args, '--upgrade-module-path "${location}/../../jvmci/graal.jar"']) return extra_jvm_args def _get_option_vars(): diff --git a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java index 21f7d5a3b329..cdcac5046ba5 100644 --- a/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java +++ b/substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java @@ -561,10 +561,12 @@ public List getBuilderJavaArgs() { */ public List getBuilderModulePath() { List result = new ArrayList<>(); - // Non-jlinked JDKs need truffle and graal-sdk on the module path since they - // don't have those modules as part of the JDK. + // Non-jlinked JDKs need truffle and word, collections, nativeimage on the + // module path since they don't have those modules as part of the JDK. Note + // that graal-sdk is now obsolete after the split in GR-43819 (#7171) if (libJvmciDir != null) { - result.addAll(getJars(libJvmciDir, "graal-sdk", "enterprise-graal")); + result.addAll(getJars(libJvmciDir, "enterprise-graal")); + result.addAll(getJars(libJvmciDir, "word", "collections", "nativeimage")); } if (modulePathBuild) { result.addAll(createTruffleBuilderModulePath()); @@ -574,19 +576,36 @@ public List getBuilderModulePath() { } private List createTruffleBuilderModulePath() { - List jars = getJars(rootDir.resolve(Paths.get("lib", "truffle")), "truffle-api", "truffle-runtime", "truffle-enterprise"); + Path libTruffleDir = rootDir.resolve(Paths.get("lib", "truffle")); + List jars = getJars(libTruffleDir, "truffle-api", "truffle-runtime", "truffle-enterprise"); if (!jars.isEmpty()) { /* * If Truffle is installed as part of the JDK we always add the builder modules of * Truffle to the builder module path. This is legacy support and should in the * future no longer be needed. */ - jars.addAll(getJars(rootDir.resolve(Paths.get("lib", "truffle")), "truffle-compiler")); + jars.addAll(getJars(libTruffleDir, "truffle-compiler")); Path builderPath = rootDir.resolve(Paths.get("lib", "truffle", "builder")); if (Files.exists(builderPath)) { jars.addAll(getJars(builderPath, "truffle-runtime-svm", "truffle-enterprise-svm")); + if (libJvmciDir != null) { + // truffle-runtime-svm depends on polyglot, which is not part of non-jlinked + // JDKs + jars.addAll(getJars(libJvmciDir, "polyglot")); + } + } + if (libJvmciDir != null) { + // truffle-runtime depends on polyglot, which is not part of non-jlinked JDKs + jars.addAll(getJars(libTruffleDir, "jniutils")); } } + /* + * Non-Jlinked JDKs don't have truffle-compiler as part of the JDK, however the native + * image builder still needs it + */ + if (libJvmciDir != null) { + jars.addAll(getJars(libTruffleDir, "truffle-compiler")); + } return jars; } @@ -1544,7 +1563,8 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa Function substituteModulePath = useBundle() ? bundleSupport::substituteModulePath : Function.identity(); List substitutedImageModulePath = imagemp.stream().map(substituteModulePath).toList(); - Map modules = listModulesFromPath(javaExecutable, Stream.concat(mp.stream(), imagemp.stream()).distinct().toList()); + List mainClassArg = config.getGeneratorMainClass(); + Map modules = listModulesFromPath(javaExecutable, javaArgs, mainClassArg, mp.stream().distinct().toList(), imagemp.stream().distinct().toList()); if (!addModules.isEmpty()) { arguments.add("-D" + ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES + "=" + @@ -1564,7 +1584,7 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa } } - arguments.addAll(config.getGeneratorMainClass()); + arguments.addAll(mainClassArg); if (IS_AOT && OS.getCurrent().hasProcFS) { /* @@ -1715,33 +1735,41 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa /** * Resolves and lists all modules given a module path. * - * @see #callListModules(String, List) + * @see #callListModules(String, List, List, List, List) */ - private Map listModulesFromPath(String javaExecutable, Collection modulePath) { + private Map listModulesFromPath(String javaExecutable, List javaArgs, List mainClassArg, List modulePath, List imagemp) { if (modulePath.isEmpty() || !config.modulePathBuild) { return Map.of(); } String modulePathEntries = modulePath.stream() .map(Path::toString) .collect(Collectors.joining(File.pathSeparator)); - return callListModules(javaExecutable, List.of("-p", modulePathEntries)); + String imagePathEntries = imagemp.stream() + .map(Path::toString) + .collect(Collectors.joining(File.pathSeparator)); + List imagempArgs = List.of("-imagemp", imagePathEntries); + List modulePathArgs = List.of("--module-path", modulePathEntries); + return callListModules(javaExecutable, javaArgs, mainClassArg, imagempArgs, modulePathArgs); } /** - * Calls java $arguments --list-modules to list all modules and parse the output. - * The output consists of a map with module name as key and {@link Path} to jar file if the - * module is not installed as part of the JDK. If the module is installed as part of the + * Calls the image generator's --list-modules to list all modules and parses the + * output. The output consists of a map with module name as key and {@link Path} to jar file if + * the module is not installed as part of the JDK. If the module is installed as part of the * jdk/boot-layer then a null path will be returned. *

* This is a much more robust solution then trying to parse the JDK file structure manually. */ - private static Map callListModules(String javaExecutable, List arguments) { + private static Map callListModules(String javaExecutable, List javaArgs, List mainClassArg, List imagempArgs, List modulePathArgs) { Process listModulesProcess = null; Map result = new LinkedHashMap<>(); try { var pb = new ProcessBuilder(javaExecutable); - pb.command().addAll(arguments); - pb.command().add("--list-modules"); + pb.command().addAll(javaArgs); + pb.command().addAll(modulePathArgs); + pb.command().addAll(mainClassArg); + pb.command().addAll(imagempArgs); + pb.command().add("-H:+ListModules"); pb.environment().clear(); listModulesProcess = pb.start(); @@ -1758,8 +1786,10 @@ private static Map callListModules(String javaExecutable, List 1) { - String pathURI = splitString[1]; // url: file://path/to/file - externalPath = Path.of(URI.create(pathURI)).toAbsolutePath(); + String pathURI = splitString[1].trim(); // url: file://path/to/file + if (pathURI.startsWith("file://")) { + externalPath = Path.of(URI.create(pathURI)).toAbsolutePath(); + } } result.put(splitModuleNameAndVersion[0], externalPath); }