From 3492831d48712047cf75404620dfaac228c59485 Mon Sep 17 00:00:00 2001 From: Ivan Ristovic Date: Tue, 23 Jul 2024 17:45:11 +0200 Subject: [PATCH] Add system modules implicitly required by the application to the image builder module graph --- .../com/oracle/svm/driver/NativeImage.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) 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 2f2c9001f8d0..afb540d1e768 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 @@ -29,9 +29,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.lang.module.Configuration; import java.lang.module.FindException; +import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleFinder; import java.lang.module.ModuleReference; +import java.lang.module.ResolvedModule; import java.lang.reflect.Method; import java.net.URI; import java.nio.charset.StandardCharsets; @@ -60,6 +63,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Predicate; import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -1626,6 +1630,15 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa } List finalImageModulePath = applicationModules.values().stream().toList(); + /* + * Make sure to add all system modules required by the application that might not be part of + * the boot module layer of image builder. If we do not do this, the image builder will fail + * to create the image-build module layer, as it will attempt to define system modules to + * the host VM. + */ + Set implicitlyRequiredSystemModules = getImplicitlyRequiredSystemModules(finalImageModulePath); + addModules.addAll(implicitlyRequiredSystemModules); + if (!addModules.isEmpty()) { arguments.add("-D" + ModuleSupport.PROPERTY_IMAGE_EXPLICITLY_ADDED_MODULES + "=" + @@ -1825,6 +1838,36 @@ private Map getModulesFromPath(Collection modulePath) { return mrefs; } + private Set getImplicitlyRequiredSystemModules(Collection modulePath) { + if (!config.modulePathBuild || modulePath.isEmpty()) { + return Set.of(); + } + + ModuleFinder finder = ModuleFinder.of(modulePath.toArray(Path[]::new)); + Set modules = finder.findAll(); + + Set systemModules = getBuiltInModules(); + Set applicationModulePathRequiredModules = new HashSet<>(); + + int priorSize; + do { + priorSize = applicationModulePathRequiredModules.size(); + for (ModuleReference mref : modules) { + Set requiredModules = getRequiredModules(mref); + applicationModulePathRequiredModules.addAll(requiredModules); + } + } while (priorSize < applicationModulePathRequiredModules.size()); + + applicationModulePathRequiredModules.retainAll(systemModules); + return applicationModulePathRequiredModules; + } + + private Set getRequiredModules(ModuleReference mref) { + return mref.descriptor().requires().stream() + .map(ModuleDescriptor.Requires::name) + .collect(Collectors.toSet()); + } + boolean useBundle() { return bundleSupport != null; }