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 2f21d64e0b72..d026149ae6c4 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 @@ -82,12 +82,13 @@ protected void parseClass(EconomicMap data) { return; } + boolean jniAccessible = 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); + TypeResult result = delegate.resolveType(condition, typeDescriptor, true, jniAccessible); if (!result.isPresent()) { handleMissingElement("Could not resolve " + typeDescriptor + " for reflection configuration.", result.getException()); return; @@ -97,7 +98,6 @@ protected void parseClass(EconomicMap data) { T clazz = result.get(); delegate.registerType(conditionResult.get(), clazz); - boolean jniAccessible = checkOption(ConfigurationParserOption.JNI_PARSER); 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)); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParser.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParser.java index c0410bc3b96c..d71b50dcbe63 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParser.java @@ -82,16 +82,14 @@ protected void parseClassArray(List classes) { protected abstract void parseClass(EconomicMap data); - protected boolean registerIfNotDefault(EconomicMap data, boolean defaultValue, T clazz, String propertyName, Runnable register) { + protected void registerIfNotDefault(EconomicMap data, boolean defaultValue, T clazz, String propertyName, Runnable register) { if (data.containsKey(propertyName) ? asBoolean(data.get(propertyName), propertyName) : defaultValue) { try { register.run(); - return true; } catch (LinkageError e) { handleMissingElement("Could not register " + delegate.getTypeName(clazz) + ": " + propertyName + " for reflection.", e); } } - return false; } protected void parseFields(C condition, List fields, T clazz, boolean jniAccessible) { @@ -165,7 +163,7 @@ private List parseMethodParameters(T clazz, String methodName, List t List result = new ArrayList<>(); for (Object type : types) { String typeName = asString(type, "types"); - TypeResult typeResult = delegate.resolveType(conditionResolver.alwaysTrue(), NamedConfigurationTypeDescriptor.fromJSONName(typeName), true); + TypeResult typeResult = delegate.resolveType(conditionResolver.alwaysTrue(), NamedConfigurationTypeDescriptor.fromJSONName(typeName), true, false); if (!typeResult.isPresent()) { handleMissingElement("Could not register method " + formatMethod(clazz, methodName) + " for reflection.", typeResult.getException()); return null; diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParserDelegate.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParserDelegate.java index ef1b2d8cae5b..accf8176c8ec 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParserDelegate.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionConfigurationParserDelegate.java @@ -30,7 +30,7 @@ public interface ReflectionConfigurationParserDelegate { - TypeResult resolveType(C condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives); + TypeResult resolveType(C condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible); void registerType(C condition, T type); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionMetadataParser.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionMetadataParser.java index e63547bb28ea..8c8ca28d06a7 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionMetadataParser.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ReflectionMetadataParser.java @@ -71,11 +71,13 @@ protected void parseClass(EconomicMap data) { } C condition = conditionResult.get(); + boolean jniParser = checkOption(ConfigurationParserOption.JNI_PARSER); + boolean typeJniAccessible = jniParser || data.get("jniAccessible") == Boolean.TRUE; /* * Even if primitives cannot be queried through Class.forName, they can be registered to * allow getDeclaredMethods() and similar bulk queries at run time. */ - TypeResult result = delegate.resolveType(condition, type.get(), true); + TypeResult result = delegate.resolveType(condition, type.get(), true, typeJniAccessible); if (!result.isPresent()) { handleMissingElement("Could not resolve " + type.get() + " for reflection configuration.", result.getException()); return; @@ -85,7 +87,6 @@ protected void parseClass(EconomicMap data) { T clazz = result.get(); delegate.registerType(conditionResult.get(), clazz); - boolean jniParser = checkOption(ConfigurationParserOption.JNI_PARSER); delegate.registerDeclaredClasses(queryCondition, clazz); delegate.registerPublicClasses(queryCondition, clazz); if (!jniParser) { @@ -101,12 +102,9 @@ protected void parseClass(EconomicMap data) { delegate.registerDeclaredFields(queryCondition, true, jniParser, clazz); delegate.registerPublicFields(queryCondition, true, jniParser, clazz); - boolean typeJniAccessible; - if (jniParser) { - typeJniAccessible = true; - } else { + if (!jniParser) { registerIfNotDefault(data, false, clazz, "serializable", () -> delegate.registerAsSerializable(condition, clazz)); - typeJniAccessible = registerIfNotDefault(data, false, clazz, "jniAccessible", () -> delegate.registerAsJniAccessed(condition, clazz)); + registerIfNotDefault(data, false, clazz, "jniAccessible", () -> delegate.registerAsJniAccessed(condition, clazz)); } registerIfNotDefault(data, false, clazz, "allDeclaredConstructors", () -> delegate.registerDeclaredConstructors(condition, false, typeJniAccessible, clazz)); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java index d6d50bbf399e..cd6707bc10ed 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java @@ -42,7 +42,7 @@ public ParserConfigurationAdapter(TypeConfiguration configuration) { } @Override - public TypeResult resolveType(UnresolvedConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) { + public TypeResult resolveType(UnresolvedConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) { ConfigurationType type = configuration.get(condition, typeDescriptor); /* * The type is not immediately set with all elements included. These are added afterwards diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java index bf81e51df8fc..e1f7cd84b98d 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java @@ -68,14 +68,14 @@ public void registerType(ConfigurationCondition condition, Class type) { } @Override - public TypeResult> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) { - TypeResult> result = super.resolveType(condition, typeDescriptor, allowPrimitives); + public TypeResult> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) { + TypeResult> result = super.resolveType(condition, typeDescriptor, allowPrimitives, jniAccessible); if (!result.isPresent() && typeDescriptor instanceof NamedConfigurationTypeDescriptor namedDescriptor) { Throwable classLookupException = result.getException(); if (classLookupException instanceof LinkageError) { String reflectionName = ClassNameSupport.typeNameToReflectionName(namedDescriptor.name()); reflectionSupport.registerClassLookupException(condition, reflectionName, classLookupException); - } else if (throwMissingRegistrationErrors() && classLookupException instanceof ClassNotFoundException) { + } else if (throwMissingRegistrationErrors() && jniAccessible & classLookupException instanceof ClassNotFoundException) { String jniName = ClassNameSupport.typeNameToJNIName(namedDescriptor.name()); jniSupport.registerClassLookup(condition, jniName); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java index c07038ecdedb..687150cb9cb1 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/RegistryAdapter.java @@ -78,7 +78,7 @@ public void registerType(ConfigurationCondition condition, Class type) { } @Override - public TypeResult> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives) { + public TypeResult> resolveType(ConfigurationCondition condition, ConfigurationTypeDescriptor typeDescriptor, boolean allowPrimitives, boolean jniAccessible) { switch (typeDescriptor.getDescriptorType()) { case NAMED -> { String reflectionName = ClassNameSupport.typeNameToReflectionName(((NamedConfigurationTypeDescriptor) typeDescriptor).name()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionFeature.java index 55f5b5086272..13f195ecffe1 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionFeature.java @@ -294,7 +294,7 @@ public void duringSetup(DuringSetupAccess a) { reflectionData.duringSetup(access.getMetaAccess(), aUniverse); RuntimeProxyCreationSupport proxyRegistry = ImageSingletons.lookup(RuntimeProxyCreationSupport.class); RuntimeSerializationSupport serializationSupport = RuntimeSerializationSupport.singleton(); - RuntimeJNIAccessSupport jniSupport = ImageSingletons.lookup(RuntimeJNIAccessSupport.class); + RuntimeJNIAccessSupport jniSupport = SubstrateOptions.JNI.getValue() ? ImageSingletons.lookup(RuntimeJNIAccessSupport.class) : null; ReflectionConfigurationParser> parser = ConfigurationParserUtils.create(ConfigurationFile.REFLECTION, true, conditionResolver, reflectionData, proxyRegistry, serializationSupport, jniSupport, access.getImageClassLoader()); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurationsFromCombinedFile(parser, access.getImageClassLoader(), "reflection");