diff --git a/substratevm/CHANGELOG.md b/substratevm/CHANGELOG.md index 8a93c3b85ad2..d71afc078b39 100644 --- a/substratevm/CHANGELOG.md +++ b/substratevm/CHANGELOG.md @@ -27,7 +27,7 @@ This changelog summarizes major changes to GraalVM Native Image. * (GR-40463) Red Hat added experimental support for JMX, which can be enabled with the `--enable-monitoring` option (e.g. `--enable-monitoring=jmxclient,jmxserver`). * (GR-42740) Together with Red Hat, we added experimental support for JFR event streaming. * (GR-44110) Native Image now targets `x86-64-v3` by default on AMD64 and supports a new `-march` option. Use `-march=compatibility` for best compatibility (previous default) or `-march=native` for best performance if the native executable is deployed on the same machine or on a machine with the same CPU features. To list all available machine types, use `-march=list`. -* (GR-43971) Add native-image option `-E[=]` and support environment variable capturing in bundles. Previously almost all environment variables were available in the builder. To temporarily revert back to the old behaviour, env setting `NATIVE_IMAGE_SLOPPY_BUILDER_SANITATION=true` can be used. The old behaviour will be removed in a future release. +* (GR-43971) Add native-image option `-E[=]` and support environment variable capturing in bundles. Previously almost all environment variables were available in the builder. To temporarily revert back to the old behaviour, env setting `NATIVE_IMAGE_DEPRECATED_BUILDER_SANITATION=true` can be used. The old behaviour will be removed in a future release. * (GR-43382) The build output now includes a section with recommendations that help you get the best out of Native Image. ## Version 22.3.0 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 ff41637ef98a..dec08d8eb968 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 @@ -44,6 +44,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -51,6 +52,7 @@ import java.util.Map; import java.util.Optional; import java.util.Properties; +import java.util.Set; import java.util.StringJoiner; import java.util.function.BiConsumer; import java.util.function.BiFunction; @@ -1470,17 +1472,17 @@ protected int buildImage(List javaArgs, LinkedHashSet cp, LinkedHa ProcessBuilder pb = new ProcessBuilder(); pb.command(command); Map environment = pb.environment(); - String sloppySanitationKey = "NATIVE_IMAGE_SLOPPY_BUILDER_SANITATION"; - String sloppySanitationValue = System.getenv().getOrDefault(sloppySanitationKey, "false"); - if (Boolean.parseBoolean(sloppySanitationValue)) { + String deprecatedSanitationKey = "NATIVE_IMAGE_DEPRECATED_BUILDER_SANITATION"; + String deprecatedSanitationValue = System.getenv().getOrDefault(deprecatedSanitationKey, "false"); + if (Boolean.parseBoolean(deprecatedSanitationValue)) { if (useBundle()) { bundleSupport = null; - throw showError("Bundle support is not compatible with environment variable %s=%s.".formatted(sloppySanitationKey, sloppySanitationValue)); + throw showError("Bundle support is not compatible with environment variable %s=%s.".formatted(deprecatedSanitationKey, deprecatedSanitationValue)); } if (!imageBuilderEnvironment.isEmpty()) { - throw showError("Option -E[=] is not compatible with environment variable %s=%s.".formatted(sloppySanitationKey, sloppySanitationValue)); + throw showError("Option -E[=] is not compatible with environment variable %s=%s.".formatted(deprecatedSanitationKey, deprecatedSanitationValue)); } - sloppySanitizeJVMEnvironment(environment); + deprecatedSanitizeJVMEnvironment(environment); } else { sanitizeJVMEnvironment(environment, imageBuilderEnvironment); } @@ -1528,7 +1530,7 @@ boolean useBundle() { } @Deprecated - private static void sloppySanitizeJVMEnvironment(Map environment) { + private static void deprecatedSanitizeJVMEnvironment(Map environment) { String[] jvmAffectingEnvironmentVariables = {"JAVA_COMPILER", "_JAVA_OPTIONS", "JAVA_TOOL_OPTIONS", "JDK_JAVA_OPTIONS", "CLASSPATH"}; for (String affectingEnvironmentVariable : jvmAffectingEnvironmentVariables) { environment.remove(affectingEnvironmentVariable); @@ -1536,32 +1538,35 @@ private static void sloppySanitizeJVMEnvironment(Map environment } private static void sanitizeJVMEnvironment(Map environment, Map imageBuilderEnvironment) { - Map restrictedEnvironment = new HashMap<>(); - List jvmRequiredEnvironmentVariables = new ArrayList<>(List.of("PATH", "PWD", "HOME", "LANG", "LC_ALL")); - jvmRequiredEnvironmentVariables.add("SRCHOME"); // FIXME + Set requiredKeys = new HashSet<>(List.of("PATH", "PWD", "HOME", "LANG", "LC_ALL")); + requiredKeys.add("SRCHOME"); /* Remove once GR-44676 is fixed */ + Function keyMapper; if (OS.WINDOWS.isCurrent()) { - jvmRequiredEnvironmentVariables.addAll(List.of("TEMP", "INCLUDE", "LIB")); + requiredKeys.addAll(List.of("TEMP", "INCLUDE", "LIB")); + keyMapper = String::toUpperCase; + } else { + keyMapper = Function.identity(); } - for (String requiredEnvironmentVariable : jvmRequiredEnvironmentVariables) { - String val = environment.get(requiredEnvironmentVariable); - if (val != null) { - restrictedEnvironment.put(requiredEnvironmentVariable, val); + Map restrictedEnvironment = new HashMap<>(); + environment.forEach((key, val) -> { + if (requiredKeys.contains(keyMapper.apply(key))) { + restrictedEnvironment.put(key, val); } - } + }); for (Iterator> iterator = imageBuilderEnvironment.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = iterator.next(); - String requiredKey = entry.getKey(); - String requiredValue = entry.getValue(); - if (requiredValue != null) { - restrictedEnvironment.put(requiredKey, requiredValue); + if (entry.getValue() != null) { + restrictedEnvironment.put(entry.getKey(), entry.getValue()); } else { - String existingValue = environment.get(requiredKey); - if (existingValue != null) { - restrictedEnvironment.put(requiredKey, existingValue); - /* Capture found existingValue for storing vars in bundle */ - entry.setValue(existingValue); - } else { - NativeImage.showWarning("Environment variable '" + requiredKey + "' is undefined and therefore not available during image build-time."); + environment.forEach((key, val) -> { + if (keyMapper.apply(key).equals(keyMapper.apply(entry.getKey()))) { + restrictedEnvironment.put(entry.getKey(), val); + /* Capture found value for storing vars in bundle */ + entry.setValue(val); + } + }); + if (entry.getValue() == null) { + NativeImage.showWarning("Environment variable '" + entry.getKey() + "' is undefined and therefore not available during image build-time."); /* Remove undefined environment for storing vars in bundle */ iterator.remove(); }