diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationCondition.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationCondition.java index f6deb0279b14..d7c56dc0dd98 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationCondition.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationCondition.java @@ -44,11 +44,18 @@ /** * A condition that describes if a reflectively-accessed element in Native Image is visible by the - * user. + * user at run time. *

- * Currently, there is only one type of condition (typeReached) so this is a final - * class instead of the class hierarchy. The {@link ConfigurationCondition#type} represents the - * {@link Class<>} that needs to be reached by analysis in order for an element to be visible. + * Currently, there is only two types of condition: + *

  • typeReached (the default) that signifies that the type must be both reachable by + * static analysis at build time, and reached at run time. A type is reached at run time, right + * before the class-initialization routine starts for that type, or any of the type's subtypes are + * reached.
  • + *
  • typeReachable (legacy) that signifies that the type must be reachable by static + * analysis at build time.
  • + *

    + * When {@link ConfigurationCondition#runtimeChecked} is true denotes that this is a + * typeReached condition. */ public final class ConfigurationCondition { @@ -63,6 +70,25 @@ public static ConfigurationCondition alwaysTrue() { private final boolean runtimeChecked; + /** + * Creates the default type-reached condition that is satisfied when the type is reached at + * runtime. + * + * @param type that has to be reached for this condition to be satisfied + * @return instance of the condition + */ + public static ConfigurationCondition create(Class type) { + return create(type, true); + } + + /** + * Creates either a type-reached condition ({@code runtimeChecked = true}) or a type-reachable + * condition. + * + * @param type that has to be reached (or reachable) for this condition to be satisfied + * @param runtimeChecked makes this a type-reachable condition when false + * @return instance of the condition + */ public static ConfigurationCondition create(Class type, boolean runtimeChecked) { Objects.requireNonNull(type); if (JAVA_LANG_OBJECT_REACHED.getType().equals(type)) { diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java index ffaf597dcdbe..fb7a182cda99 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java @@ -53,6 +53,10 @@ public final class UnresolvedConfigurationCondition implements Comparable value : methodCallNodes.values()) { for (MethodCallNode node : value) { String className = node.methodInfo.getJavaDeclaringClassName(); - UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.create(className, true); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.create(className); var resolvedCondition = ConfigurationConditionResolver.identityResolver().resolveCondition(condition); addConfigurationWithCondition(configurationSet, node.configuration, resolvedCondition.get()); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java index 23730c8a4ca2..85911c036ce4 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationParser.java @@ -241,7 +241,7 @@ protected UnresolvedConfigurationCondition parseCondition(EconomicMap { + private final ClassInitializationSupport classInitializationSupport = ClassInitializationSupport.singleton(); + private final Set alreadyAddedResources = new HashSet<>(); ResourcesRegistryImpl() { @@ -199,6 +201,7 @@ public void addGlob(ConfigurationCondition condition, String module, String glob public void addCondition(ConfigurationCondition condition, Module module, String resourcePath) { var conditionalResource = Resources.singleton().getResourceStorage().get(createStorageKey(module, resourcePath)); if (conditionalResource != null) { + classInitializationSupport.addForTypeReachedTracking(condition.getType()); conditionalResource.getConditions().addCondition(condition); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java index 27565d7fe248..e6950f3be22a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java @@ -52,9 +52,6 @@ public TypeResult resolveCondition(UnresolvedConfigurati * reachability checks. */ var runtimeChecked = !classInitializationSupport.isAlwaysReached(type) && unresolvedCondition.isRuntimeChecked(); - if (runtimeChecked) { - classInitializationSupport.addForTypeReachedTracking(type); - } return ConfigurationCondition.create(type, runtimeChecked); }); }