From 8e0542b0819daa71b37732347d5657492556c12e Mon Sep 17 00:00:00 2001 From: Loic Ottet Date: Wed, 21 May 2025 15:52:10 +0200 Subject: [PATCH] Treat "name" entries in legacy configuration files like "type" in reachability-metadata.json --- .../LegacyReflectionConfigurationParser.java | 48 +++++++++---------- .../svm/core/FutureDefaultsOptions.java | 7 ++- .../core/configure/ConfigurationFiles.java | 3 +- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/LegacyReflectionConfigurationParser.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/LegacyReflectionConfigurationParser.java index d026149ae6c4..49e5600c44cd 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/LegacyReflectionConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/LegacyReflectionConfigurationParser.java @@ -76,19 +76,19 @@ protected void parseClass(EconomicMap data) { */ boolean isType = type.get().definedAsType(); - UnresolvedConfigurationCondition unresolvedCondition = parseCondition(data, isType); + UnresolvedConfigurationCondition unresolvedCondition = parseCondition(data, false); TypeResult conditionResult = conditionResolver.resolveCondition(unresolvedCondition); if (!conditionResult.isPresent()) { return; } - boolean jniAccessible = checkOption(ConfigurationParserOption.JNI_PARSER); + boolean jniParser = checkOption(ConfigurationParserOption.JNI_PARSER); /* * Even if primitives cannot be queried through Class.forName, they can be registered to * allow getDeclaredMethods() and similar bulk queries at run time. */ C condition = conditionResult.get(); - TypeResult result = delegate.resolveType(condition, typeDescriptor, true, jniAccessible); + TypeResult result = delegate.resolveType(condition, typeDescriptor, true, jniParser); if (!result.isPresent()) { handleMissingElement("Could not resolve " + typeDescriptor + " for reflection configuration.", result.getException()); return; @@ -98,29 +98,29 @@ protected void parseClass(EconomicMap data) { T clazz = result.get(); delegate.registerType(conditionResult.get(), clazz); - registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, false, clazz, "allPublicConstructors", () -> delegate.registerPublicConstructors(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, false, clazz, "allDeclaredMethods", () -> delegate.registerDeclaredMethods(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, false, clazz, "allPublicMethods", () -> delegate.registerPublicMethods(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, false, clazz, "allDeclaredFields", () -> delegate.registerDeclaredFields(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, false, clazz, "allPublicFields", () -> delegate.registerPublicFields(condition, false, jniAccessible, clazz)); - registerIfNotDefault(data, isType, clazz, "allDeclaredClasses", () -> delegate.registerDeclaredClasses(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "allRecordComponents", () -> delegate.registerRecordComponents(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "allPermittedSubclasses", () -> delegate.registerPermittedSubclasses(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "allNestMembers", () -> delegate.registerNestMembers(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "allSigners", () -> delegate.registerSigners(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "allPublicClasses", () -> delegate.registerPublicClasses(queryCondition, clazz)); - registerIfNotDefault(data, isType, clazz, "queryAllDeclaredConstructors", () -> delegate.registerDeclaredConstructors(queryCondition, true, jniAccessible, clazz)); - registerIfNotDefault(data, isType, clazz, "queryAllPublicConstructors", () -> delegate.registerPublicConstructors(queryCondition, true, jniAccessible, clazz)); - registerIfNotDefault(data, isType, clazz, "queryAllDeclaredMethods", () -> delegate.registerDeclaredMethods(queryCondition, true, jniAccessible, clazz)); - registerIfNotDefault(data, isType, clazz, "queryAllPublicMethods", () -> delegate.registerPublicMethods(queryCondition, true, jniAccessible, clazz)); + registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, jniParser, clazz)); + registerIfNotDefault(data, false, clazz, "allPublicConstructors", () -> delegate.registerPublicConstructors(condition, false, jniParser, clazz)); + registerIfNotDefault(data, false, clazz, "allDeclaredMethods", () -> delegate.registerDeclaredMethods(condition, false, jniParser, clazz)); + registerIfNotDefault(data, false, clazz, "allPublicMethods", () -> delegate.registerPublicMethods(condition, false, jniParser, clazz)); + registerIfNotDefault(data, false, clazz, "allDeclaredFields", () -> delegate.registerDeclaredFields(condition, false, jniParser, clazz)); + registerIfNotDefault(data, false, clazz, "allPublicFields", () -> delegate.registerPublicFields(condition, false, jniParser, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allDeclaredClasses", () -> delegate.registerDeclaredClasses(queryCondition, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allRecordComponents", () -> delegate.registerRecordComponents(queryCondition, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allPermittedSubclasses", () -> delegate.registerPermittedSubclasses(queryCondition, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allNestMembers", () -> delegate.registerNestMembers(queryCondition, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allSigners", () -> delegate.registerSigners(queryCondition, clazz)); + registerIfNotDefault(data, !jniParser && isType, clazz, "allPublicClasses", () -> delegate.registerPublicClasses(queryCondition, clazz)); + registerIfNotDefault(data, isType, clazz, "queryAllDeclaredConstructors", () -> delegate.registerDeclaredConstructors(queryCondition, true, jniParser, clazz)); + registerIfNotDefault(data, isType, clazz, "queryAllPublicConstructors", () -> delegate.registerPublicConstructors(queryCondition, true, jniParser, clazz)); + registerIfNotDefault(data, isType, clazz, "queryAllDeclaredMethods", () -> delegate.registerDeclaredMethods(queryCondition, true, jniParser, clazz)); + registerIfNotDefault(data, isType, clazz, "queryAllPublicMethods", () -> delegate.registerPublicMethods(queryCondition, true, jniParser, clazz)); if (isType) { /* * Fields cannot be registered as queried only by the user, we register them * unconditionally if the class is registered via "type". */ - delegate.registerDeclaredFields(queryCondition, true, jniAccessible, clazz); - delegate.registerPublicFields(queryCondition, true, jniAccessible, clazz); + delegate.registerDeclaredFields(queryCondition, true, jniParser, clazz); + delegate.registerPublicFields(queryCondition, true, jniParser, clazz); } registerIfNotDefault(data, false, clazz, "unsafeAllocated", () -> delegate.registerUnsafeAllocated(condition, clazz)); MapCursor cursor = data.getEntries(); @@ -130,13 +130,13 @@ protected void parseClass(EconomicMap data) { try { switch (name) { case "methods": - parseMethods(condition, false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz, jniAccessible); + parseMethods(condition, false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz, jniParser); break; case "queriedMethods": - parseMethods(condition, true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz, jniAccessible); + parseMethods(condition, true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz, jniParser); break; case "fields": - parseFields(condition, asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz, jniAccessible); + parseFields(condition, asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz, jniParser); break; } } catch (LinkageError e) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java index 6861a5c02583..1b6316095478 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/FutureDefaultsOptions.java @@ -53,10 +53,11 @@ public class FutureDefaultsOptions { private static final String ALL_NAME = "all"; private static final String NONE_NAME = "none"; private static final String RUN_TIME_INITIALIZE_JDK_NAME = "run-time-initialized-jdk"; + private static final String TREAT_NAME_AS_TYPE_NAME = "treat-name-as-type"; public static final String RUN_TIME_INITIALIZE_JDK_REASON = "Initialize JDK classes at run time (--" + OPTION_NAME + " includes " + RUN_TIME_INITIALIZE_JDK_NAME + ")"; - private static final Set ALL_VALUES = Set.of(RUN_TIME_INITIALIZE_JDK_NAME, ALL_NAME, NONE_NAME); + private static final Set ALL_VALUES = Set.of(RUN_TIME_INITIALIZE_JDK_NAME, TREAT_NAME_AS_TYPE_NAME, ALL_NAME, NONE_NAME); private static String futureDefaultsAllValues() { return StringUtil.joinSingleQuoted(ALL_VALUES); @@ -118,4 +119,8 @@ public static boolean allFutureDefaults() { public static boolean isJDKInitializedAtRunTime() { return allFutureDefaults() || getFutureDefaults().contains(RUN_TIME_INITIALIZE_JDK_NAME); } + + public static boolean treatNameAsType() { + return allFutureDefaults() || getFutureDefaults().contains(TREAT_NAME_AS_TYPE_NAME); + } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java index b8402d25f27e..74fff342b7d7 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationFiles.java @@ -41,6 +41,7 @@ import com.oracle.svm.configure.ConfigurationFile; import com.oracle.svm.configure.ConfigurationParserOption; +import com.oracle.svm.core.FutureDefaultsOptions; import com.oracle.svm.core.option.AccumulatingLocatableMultiOptionValue; import com.oracle.svm.core.option.BundleMember; import com.oracle.svm.core.option.HostedOptionKey; @@ -190,7 +191,7 @@ public static EnumSet getConfigurationParserOptions() if (TreatAllTypeReachableConditionsAsTypeReached.getValue()) { result.add(ConfigurationParserOption.TREAT_ALL_TYPE_REACHABLE_CONDITIONS_AS_TYPE_REACHED); } - if (TreatAllNameEntriesAsType.getValue()) { + if (TreatAllNameEntriesAsType.getValue() || FutureDefaultsOptions.treatNameAsType()) { result.add(ConfigurationParserOption.TREAT_ALL_NAME_ENTRIES_AS_TYPE); } return result;