Skip to content

Commit 306c2e7

Browse files
committed
Future default class-for-name-respects-class-loader
1 parent 5975f9f commit 306c2e7

File tree

3 files changed

+59
-40
lines changed

3 files changed

+59
-40
lines changed

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

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

27-
import java.util.Collections;
28-
import java.util.LinkedHashSet;
29-
import java.util.List;
30-
import java.util.Objects;
31-
import java.util.Set;
32-
import java.util.stream.Collectors;
33-
34-
import org.graalvm.nativeimage.ImageInfo;
35-
import org.graalvm.nativeimage.Platform;
36-
import org.graalvm.nativeimage.Platforms;
37-
27+
import com.oracle.svm.core.hub.ClassForNameSupport;
3828
import com.oracle.svm.core.option.APIOption;
3929
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
4030
import com.oracle.svm.core.option.HostedOptionKey;
@@ -43,9 +33,20 @@
4333
import com.oracle.svm.core.util.VMError;
4434
import com.oracle.svm.util.LogUtils;
4535
import com.oracle.svm.util.StringUtil;
46-
4736
import jdk.graal.compiler.options.Option;
37+
import jdk.graal.compiler.options.OptionKey;
4838
import jdk.graal.compiler.options.OptionType;
39+
import org.graalvm.collections.EconomicMap;
40+
import org.graalvm.nativeimage.ImageInfo;
41+
import org.graalvm.nativeimage.Platform;
42+
import org.graalvm.nativeimage.Platforms;
43+
44+
import java.util.Collections;
45+
import java.util.LinkedHashSet;
46+
import java.util.List;
47+
import java.util.Objects;
48+
import java.util.Set;
49+
import java.util.stream.Collectors;
4950

5051
/**
5152
* Enables the --future-defaults=value flag that is used for evolution of Native Image semantics.
@@ -81,13 +82,14 @@ public class FutureDefaultsOptions {
8182
private static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS = "run-time-initialize-security-providers";
8283
private static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS = "run-time-initialize-file-system-providers";
8384
private static final String RUN_TIME_INITIALIZE_RESOURCE_BUNDLES = "run-time-initialize-resource-bundles";
84-
private static final List<String> ALL_FUTURE_DEFAULTS = List.of(RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS, RUN_TIME_INITIALIZE_SECURITY_PROVIDERS, RUN_TIME_INITIALIZE_RESOURCE_BUNDLES);
85+
private static final String CLASS_FOR_NAME_RESPECTS_CLASS_LOADER = "class-for-name-respects-class-loader";
86+
private static final List<String> ALL_FUTURE_DEFAULTS = List.of(CLASS_FOR_NAME_RESPECTS_CLASS_LOADER, RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS, RUN_TIME_INITIALIZE_SECURITY_PROVIDERS, RUN_TIME_INITIALIZE_RESOURCE_BUNDLES);
8587

8688
private static final String COMPLETE_REFLECTION_TYPES = "complete-reflection-types";
8789
private static final List<String> RETIRED_FUTURE_DEFAULTS = List.of(COMPLETE_REFLECTION_TYPES);
8890

89-
public static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS +
90-
")";
91+
public static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + CLASS_FOR_NAME_RESPECTS_CLASS_LOADER +
92+
")";
9193
public static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_SECURITY_PROVIDERS + ")";
9294
public static final String RUN_TIME_INITIALIZE_RESOURCE_BUNDLES_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_RESOURCE_BUNDLES + ")";
9395
private static final String DEFAULT_NAME = "<default-value>";
@@ -107,12 +109,21 @@ private static LinkedHashSet<String> getAllValues() {
107109
@APIOption(name = OPTION_NAME, defaultValue = DEFAULT_NAME) //
108110
@Option(help = "file:doc-files/FutureDefaultsHelp.txt", type = OptionType.User) //
109111
static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> FutureDefaults = new HostedOptionKey<>(
110-
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
112+
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter()) {
113+
@Override
114+
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, AccumulatingLocatableMultiOptionValue.Strings oldValue, AccumulatingLocatableMultiOptionValue.Strings newValue) {
115+
super.onValueUpdate(values, oldValue, newValue);
116+
/* temporary simple pwdctest, will do full parsing */
117+
if (newValue.values().contains("all") || newValue.values().contains(CLASS_FOR_NAME_RESPECTS_CLASS_LOADER)) {
118+
ClassForNameSupport.Options.ClassForNameRespectsClassLoader.update(values, true);
119+
}
120+
}
121+
};
111122

112123
private static String getOptionHelpText() {
113124
Objects.requireNonNull(FutureDefaultsOptions.FutureDefaults.getDescriptor(), "This must be called after the options are processed.");
114125
return FutureDefaultsOptions.FutureDefaults.getDescriptor().getHelp().stream()
115-
.collect(Collectors.joining(System.lineSeparator()));
126+
.collect(Collectors.joining(System.lineSeparator()));
116127
}
117128

118129
private static void verifyOptionDescription() {
@@ -124,7 +135,14 @@ private static void verifyOptionDescription() {
124135
}
125136
}
126137
if (!optionHelpText.contains(futureDefaultsAllValues())) {
127-
throw VMError.shouldNotReachHere("Must mention all options in a comma-separated sequence: " + futureDefaultsAllValues());
138+
throw VMError.shouldNotReachHere("Must mention all options in a comma-separated in the exact order: " + futureDefaultsAllValues());
139+
}
140+
141+
/* Ensure retired future-defaults are not mentioned in user-facing help text */
142+
for (String retired : RETIRED_FUTURE_DEFAULTS) {
143+
if (optionHelpText.contains("'" + retired + "'")) {
144+
throw VMError.shouldNotReachHere("Must not mention retired options in the help text. Retired option: " + retired);
145+
}
128146
}
129147
}
130148

@@ -139,35 +157,35 @@ public static void parseAndVerifyOptions() {
139157
String value = valueWithOrigin.value();
140158
if (DEFAULT_NAME.equals(value)) {
141159
throw UserError.abort("The '%s' from %s is forbidden. It can only contain: %s.%n%nUsage:%n%n%s",
142-
SubstrateOptionsParser.commandArgument(FutureDefaults, DEFAULT_NAME),
143-
valueWithOrigin.origin(),
144-
futureDefaultsAllValues(),
145-
getOptionHelpText());
160+
SubstrateOptionsParser.commandArgument(FutureDefaults, DEFAULT_NAME),
161+
valueWithOrigin.origin(),
162+
futureDefaultsAllValues(),
163+
getOptionHelpText());
146164
}
147165

148166
if (RETIRED_FUTURE_DEFAULTS.contains(value)) {
149167
LogUtils.warning("The '%s' option from %s contains the value '%s' which is enabled by default in this GraalVM release (%s) and can be removed.",
150-
SubstrateOptionsParser.commandArgument(FutureDefaults, value),
151-
valueWithOrigin.origin(),
152-
value,
153-
VM.getVersion());
168+
SubstrateOptionsParser.commandArgument(FutureDefaults, value),
169+
valueWithOrigin.origin(),
170+
value,
171+
VM.getVersion());
154172
return;
155173
}
156174

157175
if (!getAllValues().contains(value)) {
158176
throw UserError.abort("The '%s' option from %s contains invalid value '%s'. It can only contain: %s.%n%nUsage:%n%n%s",
159-
SubstrateOptionsParser.commandArgument(FutureDefaults, value),
160-
valueWithOrigin.origin(),
161-
value,
162-
futureDefaultsAllValues(),
163-
getOptionHelpText());
177+
SubstrateOptionsParser.commandArgument(FutureDefaults, value),
178+
valueWithOrigin.origin(),
179+
value,
180+
futureDefaultsAllValues(),
181+
getOptionHelpText());
164182
}
165183

166184
if (value.equals(NONE_NAME)) {
167185
if (!valueWithOrigin.origin().commandLineLike()) {
168186
throw UserError.abort("The '%s' option can only be used from the command line. Detected usage from %s.",
169-
SubstrateOptionsParser.commandArgument(FutureDefaults, NONE_NAME),
170-
valueWithOrigin.origin());
187+
SubstrateOptionsParser.commandArgument(FutureDefaults, NONE_NAME),
188+
valueWithOrigin.origin());
171189
}
172190
futureDefaults.clear();
173191
}
@@ -183,16 +201,16 @@ public static void parseAndVerifyOptions() {
183201

184202
/* Set build-time properties for user features */
185203
for (String futureDefault : getFutureDefaults()) {
186-
setSystemProperty(futureDefault, true);
204+
setSystemProperty(futureDefault);
187205
}
188206

189207
for (String retiredFutureDefault : RETIRED_FUTURE_DEFAULTS) {
190-
setSystemProperty(retiredFutureDefault, true);
208+
setSystemProperty(retiredFutureDefault);
191209
}
192210
}
193211

194-
private static void setSystemProperty(String futureDefault, boolean value) {
195-
System.setProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.toString(value));
212+
private static void setSystemProperty(String futureDefault) {
213+
System.setProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.toString(true));
196214
}
197215

198216
public static Set<String> getFutureDefaults() {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Enable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'none', 'run-time-initialize-jdk', 'run-time-initialize-file-system-providers', 'run-time-initialize-security-providers', 'run-time-initialize-resource-bundles', 'complete-reflection-types'. The preferred usage is '--future-defaults=all'.
1+
Enable options that are planned to become defaults in future releases. Comma-separated list can contain 'all', 'none', 'run-time-initialize-jdk', 'class-for-name-respects-class-loader', 'run-time-initialize-file-system-providers', 'run-time-initialize-security-providers', 'run-time-initialize-resource-bundles'. The preferred usage is '--future-defaults=all'.
22

33
The meaning of each possible option is as follows:
44
'all' - is the preferred option, and it enables all other behaviors.
@@ -7,10 +7,10 @@ The meaning of each possible option is as follows:
77

88
'run-time-initialize-jdk' - enables all behaviors related to run-time initialization of the JDK: ['run-time-initialize-security-providers', 'run-time-initialize-file-system-providers', 'run-time-initialize-resource-bundles'].
99

10-
'complete-reflection-types' - reflective registration of a type, via metadata files or the Feature API, always includes all type metadata. Now, all registered types behave the same as types defined in 'reachability-metadata.json'.
10+
'class-for-name-respects-class-loader' - `Class.forName` and similar respect their class loader argument.
1111

1212
'run-time-initialize-security-providers' - shifts away from build-time initialization for 'java.security.Provider'. Unless you store 'java.security.Provider'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
1313

1414
'run-time-initialize-file-system-providers' - shifts away from build-time initialization for 'java.nio.file.spi.FileSystemProvider'. Unless you store 'FileSystemProvider'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
1515

16-
'run-time-initialize-resource-bundles' - shifts away from build-time initialization for 'java.util.ResourceBundle'. Unless you store 'ResourceBundle'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.
16+
'run-time-initialize-resource-bundles' - shifts away from build-time initialization for 'java.util.ResourceBundle'. Unless you store 'ResourceBundle'-related classes in the image heap, this option should not affect you. In case this option breaks your build, follow the suggestions in the error messages.

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.util.function.BooleanSupplier;
4040
import java.util.function.Consumer;
4141

42+
import com.oracle.svm.core.FutureDefaultsOptions;
4243
import org.graalvm.collections.EconomicMap;
4344
import org.graalvm.nativeimage.Platform;
4445
import org.graalvm.nativeimage.Platform.HOSTED_ONLY;

0 commit comments

Comments
 (0)