Skip to content

Commit 0579681

Browse files
committed
The compatibility mode for Native Image
The goal of this mode is to behave exactly the same like the underlying language: no build-time initialization on classpath classes, no custom system properties for native image, no substitutions on classpath classes, no user features. Run-time class loading and future defaults are enabled by default.
1 parent 09f6122 commit 0579681

10 files changed

Lines changed: 86 additions & 17 deletions

File tree

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixSystemPropertiesSupport.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@
3636

3737
public abstract class PosixSystemPropertiesSupport extends SystemPropertiesSupport {
3838

39+
public PosixSystemPropertiesSupport(boolean compatibilityMode) {
40+
super(compatibilityMode);
41+
}
42+
3943
@Override
4044
protected String jvmLibName() {
4145
return "libjvm" + jvmLibSuffix();

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinSystemPropertiesSupport.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.posix.darwin;
2626

27-
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928
import org.graalvm.nativeimage.Platform;
3029
import org.graalvm.nativeimage.c.function.CLibrary;
@@ -38,6 +37,7 @@
3837
import com.oracle.svm.core.feature.InternalFeature;
3938
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
4039
import com.oracle.svm.core.headers.LibC;
40+
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
4141
import com.oracle.svm.core.posix.PosixSystemPropertiesSupport;
4242
import com.oracle.svm.core.posix.headers.Limits;
4343
import com.oracle.svm.core.posix.headers.Stdlib;
@@ -48,13 +48,18 @@
4848
import com.oracle.svm.core.traits.BuiltinTraits.NoLayeredCallbacks;
4949
import com.oracle.svm.core.traits.SingletonLayeredInstallationKind.Disallowed;
5050
import com.oracle.svm.core.traits.SingletonTraits;
51+
import com.oracle.svm.hosted.NativeImageOptions;
5152

5253
import jdk.graal.compiler.word.Word;
5354

5455
@SingletonTraits(access = AllAccess.class, layeredCallbacks = NoLayeredCallbacks.class, layeredInstallationKind = Disallowed.class)
5556
@CLibrary(value = "darwin", requireStatic = true)
5657
public class DarwinSystemPropertiesSupport extends PosixSystemPropertiesSupport {
5758

59+
public DarwinSystemPropertiesSupport(boolean compatibilityMode) {
60+
super(compatibilityMode);
61+
}
62+
5863
@Override
5964
protected String javaIoTmpdirValue() {
6065
/* Darwin has a per-user temp dir */
@@ -144,7 +149,7 @@ protected String jvmLibSuffix() {
144149
class DarwinSystemPropertiesFeature implements InternalFeature {
145150
@Override
146151
public void duringSetup(DuringSetupAccess access) {
147-
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new DarwinSystemPropertiesSupport());
152+
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new DarwinSystemPropertiesSupport(NativeImageOptions.compatibilityMode()));
148153
ImageSingletons.add(SystemPropertiesSupport.class, (SystemPropertiesSupport) ImageSingletons.lookup(RuntimeSystemPropertiesSupport.class));
149154
}
150155
}

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/linux/LinuxSystemPropertiesSupport.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package com.oracle.svm.core.posix.linux;
2626

2727
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
28+
import com.oracle.svm.hosted.NativeImageOptions;
2829
import org.graalvm.nativeimage.ImageSingletons;
2930
import org.graalvm.nativeimage.c.type.CCharPointer;
3031
import org.graalvm.nativeimage.c.type.CTypeConversion;
@@ -48,6 +49,10 @@
4849
@SingletonTraits(access = AllAccess.class, layeredCallbacks = SingleLayer.class, layeredInstallationKind = InitialLayerOnly.class)
4950
public class LinuxSystemPropertiesSupport extends PosixSystemPropertiesSupport {
5051

52+
public LinuxSystemPropertiesSupport(boolean compatibilityMode) {
53+
super(compatibilityMode);
54+
}
55+
5156
@Override
5257
protected String javaIoTmpdirValue() {
5358
/*
@@ -112,7 +117,7 @@ public boolean isInConfiguration(IsInConfigurationAccess access) {
112117

113118
@Override
114119
public void duringSetup(DuringSetupAccess access) {
115-
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new LinuxSystemPropertiesSupport());
120+
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new LinuxSystemPropertiesSupport(NativeImageOptions.compatibilityMode()));
116121
ImageSingletons.add(SystemPropertiesSupport.class, (SystemPropertiesSupport) ImageSingletons.lookup(RuntimeSystemPropertiesSupport.class));
117122
}
118123
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.nio.CharBuffer;
2929
import java.nio.charset.StandardCharsets;
3030

31+
import com.oracle.svm.hosted.NativeImageOptions;
3132
import org.graalvm.nativeimage.ImageSingletons;
3233
import org.graalvm.nativeimage.Platform;
3334
import org.graalvm.nativeimage.c.struct.SizeOf;
@@ -75,6 +76,10 @@ public class WindowsSystemPropertiesSupport extends SystemPropertiesSupport {
7576
private static final int VER_PLATFORM_WIN32_WINDOWS = 1;
7677
private static final int VER_PLATFORM_WIN32_NT = 2;
7778

79+
public WindowsSystemPropertiesSupport(boolean compatibilityMode) {
80+
super(compatibilityMode);
81+
}
82+
7883
@Override
7984
protected String userNameValue() {
8085
WCharPointer userName = WindowsLibC._wgetenv(NonmovableArrays.addressOf(NonmovableArrays.fromImageHeap(USERNAME), 0));
@@ -407,7 +412,7 @@ private void computeOsNameAndVersion() {
407412
class WindowsSystemPropertiesFeature implements InternalFeature {
408413
@Override
409414
public void duringSetup(DuringSetupAccess access) {
410-
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new WindowsSystemPropertiesSupport());
415+
ImageSingletons.add(RuntimeSystemPropertiesSupport.class, new WindowsSystemPropertiesSupport(NativeImageOptions.compatibilityMode()));
411416
ImageSingletons.add(SystemPropertiesSupport.class, (SystemPropertiesSupport) ImageSingletons.lookup(RuntimeSystemPropertiesSupport.class));
412417
}
413418
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private static LinkedHashSet<String> getAllValues() {
106106

107107
@APIOption(name = OPTION_NAME, defaultValue = DEFAULT_NAME) //
108108
@Option(help = "file:doc-files/FutureDefaultsHelp.txt", type = OptionType.User) //
109-
static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> FutureDefaults = new HostedOptionKey<>(
109+
public static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> FutureDefaults = new HostedOptionKey<>(
110110
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
111111

112112
private static String getOptionHelpText() {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public static SystemPropertiesSupport singleton() {
121121

122122
@Platforms(Platform.HOSTED_ONLY.class)
123123
@SuppressWarnings("this-escape")
124-
protected SystemPropertiesSupport() {
124+
protected SystemPropertiesSupport(boolean compatibilityMode) {
125125
for (String key : HOSTED_PROPERTIES) {
126126
String value = System.getProperty(key);
127127
if (value != null) {
@@ -146,13 +146,15 @@ protected SystemPropertiesSupport() {
146146
initializeProperty("java.ext.dirs", "");
147147
initializeProperty("sun.arch.data.model", Integer.toString(ConfigurationValues.getTarget().wordJavaKind.getBitCount()));
148148

149-
initializeProperty(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_RUNTIME);
149+
if (compatibilityMode) {
150+
initializeProperty(ImageInfo.PROPERTY_IMAGE_CODE_KEY, ImageInfo.PROPERTY_IMAGE_CODE_VALUE_RUNTIME);
150151

151-
for (String futureDefault : FutureDefaultsOptions.getFutureDefaults()) {
152-
initializeProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.TRUE.toString());
153-
}
154-
for (String futureDefault : FutureDefaultsOptions.getRetiredFutureDefaults()) {
155-
initializeProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.TRUE.toString());
152+
for (String futureDefault : FutureDefaultsOptions.getFutureDefaults()) {
153+
initializeProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.TRUE.toString());
154+
}
155+
for (String futureDefault : FutureDefaultsOptions.getRetiredFutureDefaults()) {
156+
initializeProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.TRUE.toString());
157+
}
156158
}
157159

158160
ArrayList<LazySystemProperty> lazyProperties = new ArrayList<>();

substratevm/src/com.oracle.svm.driver/src/com/oracle/svm/driver/NativeImage.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
import com.oracle.svm.driver.metainf.NativeImageMetaInfResourceProcessor;
104104
import com.oracle.svm.driver.metainf.NativeImageMetaInfWalker;
105105
import com.oracle.svm.hosted.NativeImageGeneratorRunner;
106+
import com.oracle.svm.hosted.NativeImageOptions;
106107
import com.oracle.svm.hosted.NativeImageSystemClassLoader;
107108
import com.oracle.svm.hosted.util.JDKArgsUtils;
108109
import com.oracle.svm.util.LogUtils;
@@ -123,6 +124,9 @@ public class NativeImage {
123124

124125
static final String platform = getPlatform();
125126

127+
// to avoid pulling in hosted classes
128+
public static final String COMPATIBILITY_MODE_FLAG_NAME = NativeImageOptions.CompatibilityMode.getName();
129+
126130
private static String getPlatform() {
127131
return (OS.getCurrent().className + "-" + SubstrateUtil.getArchitectureName()).toLowerCase(Locale.ROOT);
128132
}
@@ -723,9 +727,11 @@ public boolean processMetaInfResource(Path classpathEntry, Path resourceRoot, Pa
723727
if (imageNameValue != null) {
724728
addPlainImageBuilderArg(oHName + resolver.apply(imageNameValue), resourcePath.toUri().toString());
725729
}
726-
forEachPropertyValue(properties.get("JavaArgs"), NativeImage.this::addImageBuilderJavaArgs, resolver);
727-
forEachPropertyValue(properties.get("Args"), args, resolver);
728-
forEachPropertyValue(properties.get("ProvidedHostedOptions"), apiOptionHandler::injectKnownHostedOption, resolver);
730+
if (!isCompatibilityModeEnabled()) {
731+
forEachPropertyValue(properties.get("JavaArgs"), NativeImage.this::addImageBuilderJavaArgs, resolver);
732+
forEachPropertyValue(properties.get("Args"), args, resolver);
733+
forEachPropertyValue(properties.get("ProvidedHostedOptions"), apiOptionHandler::injectKnownHostedOption, resolver);
734+
}
729735
} else {
730736
args.accept(oH(type.optionKey) + resourceRoot.relativize(resourcePath));
731737
}
@@ -1365,7 +1371,12 @@ private record ArgumentEntry(int index, String value) {
13651371
}
13661372

13671373
private static Boolean getHostedOptionBooleanArgumentValue(List<String> args, OptionKey<Boolean> option) {
1368-
String locationAgnosticBooleanPattern = "^" + oH + "[+-]" + option.getName() + "(@[^=]*)?$";
1374+
String name = option.getName();
1375+
return getHostedOptionBooleanArgumentValue(args, name);
1376+
}
1377+
1378+
private static Boolean getHostedOptionBooleanArgumentValue(List<String> args, String optionName) {
1379+
String locationAgnosticBooleanPattern = "^" + oH + "[+-]" + optionName + "(@[^=]*)?$";
13691380
Pattern pattern = Pattern.compile(locationAgnosticBooleanPattern);
13701381
Boolean result = null;
13711382
for (String arg : args) {
@@ -1377,6 +1388,10 @@ private static Boolean getHostedOptionBooleanArgumentValue(List<String> args, Op
13771388
return result;
13781389
}
13791390

1391+
private boolean isCompatibilityModeEnabled() {
1392+
return Boolean.TRUE.equals(getHostedOptionBooleanArgumentValue(imageBuilderArgs, COMPATIBILITY_MODE_FLAG_NAME));
1393+
}
1394+
13801395
private boolean shouldAddCWDToCP() {
13811396
if (printFlagsOptionQuery != null || printFlagsWithExtraHelpOptionQuery != null) {
13821397
return false;

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageOptions.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
*/
2525
package com.oracle.svm.hosted;
2626

27+
import static com.oracle.svm.core.jdk.JRTSupport.Options.AllowJRTFileSystem;
28+
import static com.oracle.svm.hosted.jdk.localization.LocalizationFeature.Options.IncludeAllLocales;
2729
import static jdk.graal.compiler.options.OptionType.Debug;
2830
import static jdk.graal.compiler.options.OptionType.User;
2931

@@ -33,10 +35,13 @@
3335
import java.util.Date;
3436
import java.util.concurrent.ForkJoinPool;
3537

38+
import jdk.graal.compiler.api.replacements.Fold;
3639
import org.graalvm.collections.EconomicMap;
3740

3841
import com.oracle.graal.pointsto.reports.ReportUtils;
42+
import com.oracle.svm.core.FutureDefaultsOptions;
3943
import com.oracle.svm.core.SubstrateOptions;
44+
import com.oracle.svm.core.hub.RuntimeClassLoading;
4045
import com.oracle.svm.core.option.APIOption;
4146
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
4247
import com.oracle.svm.core.option.BundleMember;
@@ -301,4 +306,24 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
301306
}
302307
}
303308
};
309+
310+
@Option(help = "Remove all Native-Image-specific behavior from build time or runtime for classpath/module-path classes.")//
311+
public static final HostedOptionKey<Boolean> CompatibilityMode = new HostedOptionKey<>(false) {
312+
@Override
313+
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean oldValue, Boolean newValue) {
314+
super.onValueUpdate(values, oldValue, newValue);
315+
if (newValue) {
316+
FutureDefaultsOptions.FutureDefaults.update(values, "all");
317+
RuntimeClassLoading.Options.RuntimeClassLoading.update(values, true);
318+
AllowJRTFileSystem.update(values, true);
319+
IncludeAllLocales.update(values, true);
320+
}
321+
}
322+
};
323+
324+
@Fold
325+
public static boolean compatibilityMode() {
326+
return CompatibilityMode.getValue();
327+
}
328+
304329
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotationSubstitutionProcessor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,11 @@ protected void handleClass(Class<?> annotatedClass, Set<Module> builderModules)
397397
return;
398398
}
399399

400+
boolean userSubstitution = !builderModules.contains(annotatedClass.getModule());
401+
if (NativeImageOptions.compatibilityMode() && userSubstitution) {
402+
return;
403+
}
404+
400405
TargetClass targetClassAnnotation = lookupAnnotation(annotatedClass, TargetClass.class);
401406
Class<?> originalClass = findTargetClass(annotatedClass, targetClassAnnotation);
402407
if (originalClass == null) {
@@ -415,7 +420,6 @@ protected void handleClass(Class<?> annotatedClass, Set<Module> builderModules)
415420
int numAnnotations = (deleteAnnotation != null ? 1 : 0) + (substituteAnnotation != null ? 1 : 0);
416421
guarantee(numAnnotations <= 1, "Only one of @Delete or @Substitute can be used: %s", annotatedClass);
417422

418-
boolean userSubstitution = !builderModules.contains(annotatedClass.getModule());
419423
if (deleteAnnotation != null) {
420424
handleDeletedClass(originalClass, deleteAnnotation);
421425
} else if (substituteAnnotation != null) {

web-image/src/com.oracle.svm.webimage/src/com/oracle/svm/webimage/WebImageSystemPropertiesSupport.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
public class WebImageSystemPropertiesSupport extends SystemPropertiesSupport {
3232

33+
public WebImageSystemPropertiesSupport() {
34+
super(false);
35+
}
36+
3337
@Override
3438
protected String userNameValue() {
3539
return "No user name";

0 commit comments

Comments
 (0)