Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
import java.util.Set;
import java.util.stream.Collectors;

import org.graalvm.collections.EconomicMap;
import org.graalvm.nativeimage.ImageInfo;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;

import com.oracle.svm.core.hub.ClassForNameSupport;
import com.oracle.svm.core.option.APIOption;
import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue;
import com.oracle.svm.core.option.HostedOptionKey;
Expand All @@ -45,6 +47,7 @@
import com.oracle.svm.util.StringUtil;

import jdk.graal.compiler.options.Option;
import jdk.graal.compiler.options.OptionKey;
import jdk.graal.compiler.options.OptionType;

/**
Expand Down Expand Up @@ -81,12 +84,14 @@ public class FutureDefaultsOptions {
private static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS = "run-time-initialize-security-providers";
private static final String RUN_TIME_INITIALIZE_FILE_SYSTEM_PROVIDERS = "run-time-initialize-file-system-providers";
private static final String RUN_TIME_INITIALIZE_RESOURCE_BUNDLES = "run-time-initialize-resource-bundles";
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);
private static final String CLASS_FOR_NAME_RESPECTS_CLASS_LOADER = "class-for-name-respects-class-loader";
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);

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

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 +
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 +
")";
public static final String RUN_TIME_INITIALIZE_SECURITY_PROVIDERS_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_SECURITY_PROVIDERS + ")";
public static final String RUN_TIME_INITIALIZE_RESOURCE_BUNDLES_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_RESOURCE_BUNDLES + ")";
Expand All @@ -107,7 +112,16 @@ private static LinkedHashSet<String> getAllValues() {
@APIOption(name = OPTION_NAME, defaultValue = DEFAULT_NAME) //
@Option(help = "file:doc-files/FutureDefaultsHelp.txt", type = OptionType.User) //
static final HostedOptionKey<AccumulatingLocatableMultiOptionValue.Strings> FutureDefaults = new HostedOptionKey<>(
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter());
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter()) {
@Override
protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, AccumulatingLocatableMultiOptionValue.Strings oldValue, AccumulatingLocatableMultiOptionValue.Strings newValue) {
super.onValueUpdate(values, oldValue, newValue);
/* temporary simple pwdctest, will do full parsing */
if (newValue.values().contains("all") || newValue.values().contains(CLASS_FOR_NAME_RESPECTS_CLASS_LOADER)) {
ClassForNameSupport.Options.ClassForNameRespectsClassLoader.update(values, true);
}
}
};

private static String getOptionHelpText() {
Objects.requireNonNull(FutureDefaultsOptions.FutureDefaults.getDescriptor(), "This must be called after the options are processed.");
Expand All @@ -124,7 +138,14 @@ private static void verifyOptionDescription() {
}
}
if (!optionHelpText.contains(futureDefaultsAllValues())) {
throw VMError.shouldNotReachHere("Must mention all options in a comma-separated sequence: " + futureDefaultsAllValues());
throw VMError.shouldNotReachHere("Must mention all options in a comma-separated in the exact order: " + futureDefaultsAllValues());
}

/* Ensure retired future-defaults are not mentioned in user-facing help text */
for (String retired : RETIRED_FUTURE_DEFAULTS) {
if (optionHelpText.contains("'" + retired + "'")) {
throw VMError.shouldNotReachHere("Must not mention retired options in the help text. Retired option: " + retired);
}
}
}

Expand Down Expand Up @@ -183,16 +204,16 @@ public static void parseAndVerifyOptions() {

/* Set build-time properties for user features */
for (String futureDefault : getFutureDefaults()) {
setSystemProperty(futureDefault, true);
setSystemProperty(futureDefault);
}

for (String retiredFutureDefault : RETIRED_FUTURE_DEFAULTS) {
setSystemProperty(retiredFutureDefault, true);
setSystemProperty(retiredFutureDefault);
}
}

private static void setSystemProperty(String futureDefault, boolean value) {
System.setProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.toString(value));
private static void setSystemProperty(String futureDefault) {
System.setProperty(FutureDefaultsOptions.SYSTEM_PROPERTY_PREFIX + futureDefault, Boolean.toString(true));
}

public static Set<String> getFutureDefaults() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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'.
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'.

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

'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'].

'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'.
'class-for-name-respects-class-loader' - `Class.forName` and similar respect their class loader argument.

'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.

'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.

'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.
'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.
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,9 @@ public static boolean isUnsafeAllocatedPreserved(Class<?> jClass) {
}

public static boolean isRegisteredClass(String className) {
if (!ClassNameSupport.isValidReflectionName(className)) {
return true;
}
if (respectClassLoader()) {
RuntimeDynamicAccessMetadata dynamicAccessMetadata = getDynamicAccessMetadataForName(className);
if (dynamicAccessMetadata == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ private Class<?> resolve(String name, ClassLoader loader) throws ClassNotFoundEx
arrayDimensions++;
}
if (arrayDimensions == name.length()) {
if (loader == null) {
return null;
}
throw new ClassNotFoundException(name);
}
Class<?> elementalResult;
Expand Down Expand Up @@ -271,7 +274,7 @@ private static Class<?> getArrayClass(String name, Class<?> elementalResult, int
if (RuntimeClassLoading.isSupported()) {
RuntimeClassLoading.getOrCreateArrayHub(hub);
} else {
if (throwMissingRegistrationErrors()) {
if (throwMissingRegistrationErrors() && shouldFollowReflectionConfiguration() && !ClassForNameSupport.isRegisteredClass(name)) {
MissingReflectionRegistrationUtils.reportClassAccess(name);
}
return null;
Expand Down