Skip to content

Commit 33744ce

Browse files
committed
Make the reflection parser handle the case when JNI is disabled
1 parent f0d0195 commit 33744ce

File tree

8 files changed

+31
-35
lines changed

8 files changed

+31
-35
lines changed

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/LegacyReflectionConfigurationParser.java

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ protected void parseClass(EconomicMap<String, Object> data) {
8787
* allow getDeclaredMethods() and similar bulk queries at run time.
8888
*/
8989
C condition = conditionResult.get();
90-
TypeResult<T> result = delegate.resolveType(condition, typeDescriptor, true);
90+
TypeResult<T> result = delegate.resolveType(condition, typeDescriptor, true, jniParser);
9191
if (!result.isPresent()) {
9292
handleMissingElement("Could not resolve " + typeDescriptor + " for reflection configuration.", result.getException());
9393
return;
@@ -97,30 +97,29 @@ protected void parseClass(EconomicMap<String, Object> data) {
9797
T clazz = result.get();
9898
delegate.registerType(conditionResult.get(), clazz);
9999

100-
boolean jniAccessible = checkOption(ConfigurationParserOption.JNI_PARSER);
101-
registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, jniAccessible, clazz));
102-
registerIfNotDefault(data, false, clazz, "allPublicConstructors", () -> delegate.registerPublicConstructors(condition, false, jniAccessible, clazz));
103-
registerIfNotDefault(data, false, clazz, "allDeclaredMethods", () -> delegate.registerDeclaredMethods(condition, false, jniAccessible, clazz));
104-
registerIfNotDefault(data, false, clazz, "allPublicMethods", () -> delegate.registerPublicMethods(condition, false, jniAccessible, clazz));
105-
registerIfNotDefault(data, false, clazz, "allDeclaredFields", () -> delegate.registerDeclaredFields(condition, false, jniAccessible, clazz));
106-
registerIfNotDefault(data, false, clazz, "allPublicFields", () -> delegate.registerPublicFields(condition, false, jniAccessible, clazz));
100+
registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, jniParser, clazz));
101+
registerIfNotDefault(data, false, clazz, "allPublicConstructors", () -> delegate.registerPublicConstructors(condition, false, jniParser, clazz));
102+
registerIfNotDefault(data, false, clazz, "allDeclaredMethods", () -> delegate.registerDeclaredMethods(condition, false, jniParser, clazz));
103+
registerIfNotDefault(data, false, clazz, "allPublicMethods", () -> delegate.registerPublicMethods(condition, false, jniParser, clazz));
104+
registerIfNotDefault(data, false, clazz, "allDeclaredFields", () -> delegate.registerDeclaredFields(condition, false, jniParser, clazz));
105+
registerIfNotDefault(data, false, clazz, "allPublicFields", () -> delegate.registerPublicFields(condition, false, jniParser, clazz));
107106
registerIfNotDefault(data, isType, clazz, "allDeclaredClasses", () -> delegate.registerDeclaredClasses(queryCondition, clazz));
108107
registerIfNotDefault(data, isType, clazz, "allRecordComponents", () -> delegate.registerRecordComponents(queryCondition, clazz));
109108
registerIfNotDefault(data, isType, clazz, "allPermittedSubclasses", () -> delegate.registerPermittedSubclasses(queryCondition, clazz));
110109
registerIfNotDefault(data, isType, clazz, "allNestMembers", () -> delegate.registerNestMembers(queryCondition, clazz));
111110
registerIfNotDefault(data, isType, clazz, "allSigners", () -> delegate.registerSigners(queryCondition, clazz));
112111
registerIfNotDefault(data, isType, clazz, "allPublicClasses", () -> delegate.registerPublicClasses(queryCondition, clazz));
113-
registerIfNotDefault(data, isType, clazz, "queryAllDeclaredConstructors", () -> delegate.registerDeclaredConstructors(queryCondition, true, jniAccessible, clazz));
114-
registerIfNotDefault(data, isType, clazz, "queryAllPublicConstructors", () -> delegate.registerPublicConstructors(queryCondition, true, jniAccessible, clazz));
115-
registerIfNotDefault(data, isType, clazz, "queryAllDeclaredMethods", () -> delegate.registerDeclaredMethods(queryCondition, true, jniAccessible, clazz));
116-
registerIfNotDefault(data, isType, clazz, "queryAllPublicMethods", () -> delegate.registerPublicMethods(queryCondition, true, jniAccessible, clazz));
112+
registerIfNotDefault(data, isType, clazz, "queryAllDeclaredConstructors", () -> delegate.registerDeclaredConstructors(queryCondition, true, jniParser, clazz));
113+
registerIfNotDefault(data, isType, clazz, "queryAllPublicConstructors", () -> delegate.registerPublicConstructors(queryCondition, true, jniParser, clazz));
114+
registerIfNotDefault(data, isType, clazz, "queryAllDeclaredMethods", () -> delegate.registerDeclaredMethods(queryCondition, true, jniParser, clazz));
115+
registerIfNotDefault(data, isType, clazz, "queryAllPublicMethods", () -> delegate.registerPublicMethods(queryCondition, true, jniParser, clazz));
117116
if (isType) {
118117
/*
119118
* Fields cannot be registered as queried only by the user, we register them
120119
* unconditionally if the class is registered via "type".
121120
*/
122-
delegate.registerDeclaredFields(queryCondition, true, jniAccessible, clazz);
123-
delegate.registerPublicFields(queryCondition, true, jniAccessible, clazz);
121+
delegate.registerDeclaredFields(queryCondition, true, jniParser, clazz);
122+
delegate.registerPublicFields(queryCondition, true, jniParser, clazz);
124123
}
125124
registerIfNotDefault(data, false, clazz, "unsafeAllocated", () -> delegate.registerUnsafeAllocated(condition, clazz));
126125
MapCursor<String, Object> cursor = data.getEntries();
@@ -130,13 +129,13 @@ protected void parseClass(EconomicMap<String, Object> data) {
130129
try {
131130
switch (name) {
132131
case "methods":
133-
parseMethods(condition, false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz, jniAccessible);
132+
parseMethods(condition, false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz, jniParser);
134133
break;
135134
case "queriedMethods":
136-
parseMethods(condition, true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz, jniAccessible);
135+
parseMethods(condition, true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz, jniParser);
137136
break;
138137
case "fields":
139-
parseFields(condition, asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz, jniAccessible);
138+
parseFields(condition, asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz, jniParser);
140139
break;
141140
}
142141
} catch (LinkageError e) {

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParser.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,13 @@ public abstract class ReflectionConfigurationParser<C, T> extends ConditionalCon
4949

5050
protected final ConfigurationConditionResolver<C> conditionResolver;
5151
protected final ReflectionConfigurationParserDelegate<C, T> delegate;
52+
protected final boolean jniParser;
5253

5354
public ReflectionConfigurationParser(ConfigurationConditionResolver<C> conditionResolver, ReflectionConfigurationParserDelegate<C, T> delegate, EnumSet<ConfigurationParserOption> parserOptions) {
5455
super(parserOptions);
5556
this.conditionResolver = conditionResolver;
5657
this.delegate = delegate;
58+
this.jniParser = checkOption(ConfigurationParserOption.JNI_PARSER);
5759
}
5860

5961
@Override
@@ -82,16 +84,14 @@ protected void parseClassArray(List<Object> classes) {
8284

8385
protected abstract void parseClass(EconomicMap<String, Object> data);
8486

85-
protected boolean registerIfNotDefault(EconomicMap<String, Object> data, boolean defaultValue, T clazz, String propertyName, Runnable register) {
87+
protected void registerIfNotDefault(EconomicMap<String, Object> data, boolean defaultValue, T clazz, String propertyName, Runnable register) {
8688
if (data.containsKey(propertyName) ? asBoolean(data.get(propertyName), propertyName) : defaultValue) {
8789
try {
8890
register.run();
89-
return true;
9091
} catch (LinkageError e) {
9192
handleMissingElement("Could not register " + delegate.getTypeName(clazz) + ": " + propertyName + " for reflection.", e);
9293
}
9394
}
94-
return false;
9595
}
9696

9797
protected void parseFields(C condition, List<Object> fields, T clazz, boolean jniAccessible) {
@@ -165,7 +165,7 @@ private List<T> parseMethodParameters(T clazz, String methodName, List<Object> t
165165
List<T> result = new ArrayList<>();
166166
for (Object type : types) {
167167
String typeName = asString(type, "types");
168-
TypeResult<T> typeResult = delegate.resolveType(conditionResolver.alwaysTrue(), NamedConfigurationTypeDescriptor.fromJSONName(typeName), true);
168+
TypeResult<T> typeResult = delegate.resolveType(conditionResolver.alwaysTrue(), NamedConfigurationTypeDescriptor.fromJSONName(typeName), true, false);
169169
if (!typeResult.isPresent()) {
170170
handleMissingElement("Could not register method " + formatMethod(clazz, methodName) + " for reflection.", typeResult.getException());
171171
return null;

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParserDelegate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
public interface ReflectionConfigurationParserDelegate<C, T> {
3232

33-
TypeResult<T> resolveType(C condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives);
33+
TypeResult<T> resolveType(C condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible);
3434

3535
void registerType(C condition, T type);
3636

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionMetadataParser.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ protected void parseClass(EconomicMap<String, Object> data) {
7171
}
7272
C condition = conditionResult.get();
7373

74+
boolean typeJniAccessible = jniParser || data.get("jniAccessible") == Boolean.TRUE;
7475
/*
7576
* Even if primitives cannot be queried through Class.forName, they can be registered to
7677
* allow getDeclaredMethods() and similar bulk queries at run time.
7778
*/
78-
TypeResult<T> result = delegate.resolveType(condition, type.get(), true);
79+
TypeResult<T> result = delegate.resolveType(condition, type.get(), true, typeJniAccessible);
7980
if (!result.isPresent()) {
8081
handleMissingElement("Could not resolve " + type.get() + " for reflection configuration.", result.getException());
8182
return;
@@ -85,7 +86,6 @@ protected void parseClass(EconomicMap<String, Object> data) {
8586
T clazz = result.get();
8687
delegate.registerType(conditionResult.get(), clazz);
8788

88-
boolean jniParser = checkOption(ConfigurationParserOption.JNI_PARSER);
8989
delegate.registerDeclaredClasses(queryCondition, clazz);
9090
delegate.registerPublicClasses(queryCondition, clazz);
9191
if (!jniParser) {
@@ -101,12 +101,9 @@ protected void parseClass(EconomicMap<String, Object> data) {
101101
delegate.registerDeclaredFields(queryCondition, true, jniParser, clazz);
102102
delegate.registerPublicFields(queryCondition, true, jniParser, clazz);
103103

104-
boolean typeJniAccessible;
105-
if (jniParser) {
106-
typeJniAccessible = true;
107-
} else {
104+
if (!jniParser) {
108105
registerIfNotDefault(data, false, clazz, "serializable", () -> delegate.registerAsSerializable(condition, clazz));
109-
typeJniAccessible = registerIfNotDefault(data, false, clazz, "jniAccessible", () -> delegate.registerAsJniAccessed(condition, clazz));
106+
registerIfNotDefault(data, false, clazz, "jniAccessible", () -> delegate.registerAsJniAccessed(condition, clazz));
110107
}
111108

112109
registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, typeJniAccessible, clazz));

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public ParserConfigurationAdapter(TypeConfiguration configuration) {
4242
}
4343

4444
@Override
45-
public TypeResult<ConfigurationType> resolveType(UnresolvedConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) {
45+
public TypeResult<ConfigurationType> resolveType(UnresolvedConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) {
4646
ConfigurationType type = configuration.get(condition, typeDescriptor);
4747
/*
4848
* The type is not immediately set with all elements included. These are added afterwards

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ public void registerType(ConfigurationCondition condition, Class<?> type) {
6868
}
6969

7070
@Override
71-
public TypeResult<Class<?>> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) {
72-
TypeResult<Class<?>> result = super.resolveType(condition, typeDescriptor, allowPrimitives);
71+
public TypeResult<Class<?>> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) {
72+
TypeResult<Class<?>> result = super.resolveType(condition, typeDescriptor, allowPrimitives, jniAccessible);
7373
if (!result.isPresent() && typeDescriptor instanceof NamedConfigurationTypeDescriptor namedDescriptor) {
7474
Throwable classLookupException = result.getException();
7575
if (classLookupException instanceof LinkageError) {
7676
String reflectionName = ClassNameSupport.typeNameToReflectionName(namedDescriptor.name());
7777
reflectionSupport.registerClassLookupException(condition, reflectionName, classLookupException);
78-
} else if (throwMissingRegistrationErrors() && classLookupException instanceof ClassNotFoundException) {
78+
} else if (throwMissingRegistrationErrors() && jniAccessible & classLookupException instanceof ClassNotFoundException) {
7979
String jniName = ClassNameSupport.typeNameToJNIName(namedDescriptor.name());
8080
jniSupport.registerClassLookup(condition, jniName);
8181
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void registerType(ConfigurationCondition condition, Class<?> type) {
7878
}
7979

8080
@Override
81-
public TypeResult<Class<?>> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) {
81+
public TypeResult<Class<?>> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) {
8282
switch (typeDescriptor.getDescriptorType()) {
8383
case NAMED -> {
8484
String reflectionName = ClassNameSupport.typeNameToReflectionName(((NamedConfigurationTypeDescriptor) typeDescriptor).name());

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionFeature.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ public void duringSetup(DuringSetupAccess a) {
294294
reflectionData.duringSetup(access.getMetaAccess(), aUniverse);
295295
RuntimeProxyCreationSupport proxyRegistry = ImageSingletons.lookup(RuntimeProxyCreationSupport.class);
296296
RuntimeSerializationSupport<ConfigurationCondition> serializationSupport = RuntimeSerializationSupport.singleton();
297-
RuntimeJNIAccessSupport jniSupport = ImageSingletons.lookup(RuntimeJNIAccessSupport.class);
297+
RuntimeJNIAccessSupport jniSupport = SubstrateOptions.JNI.getValue() ? ImageSingletons.lookup(RuntimeJNIAccessSupport.class) : null;
298298
ReflectionConfigurationParser<ConfigurationCondition, Class<?>> parser = ConfigurationParserUtils.create(ConfigurationFile.REFLECTION, true, conditionResolver, reflectionData, proxyRegistry,
299299
serializationSupport, jniSupport, access.getImageClassLoader());
300300
loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurationsFromCombinedFile(parser, access.getImageClassLoader(), "reflection");

0 commit comments

Comments
 (0)