From fff140bbe181fab684e36a98b554224f7886c6f1 Mon Sep 17 00:00:00 2001 From: Vojin Jovanovic Date: Thu, 18 Jan 2024 15:31:09 +0100 Subject: [PATCH] Introduce the unresolved configuration condition The UnresolvedConfigurationCondition is used only during parsing and uses strings to distinguish types. The ConditionalElement is also a parsing only concept now. As a consequence all parsers are now generic in the condition that they use and they accept the ConditionResolver. --- .../hosted/RuntimeResourceAccess.java | 14 +-- .../hosted/RuntimeSerialization.java | 13 +- .../impl/ConfigurationCondition.java | 57 ++++----- .../impl/RuntimeResourceSupport.java | 20 +++- .../impl/RuntimeSerializationSupport.java | 27 +++-- .../UnresolvedConfigurationCondition.java | 102 ++++++++++++++++ substratevm/mx.substratevm/mx_substratevm.py | 2 +- .../test/config/OmitPreviousConfigTests.java | 20 ++-- .../config/ResourceConfigurationTest.java | 24 ++-- .../svm/configure/ConfigurationBase.java | 7 +- .../ConfigurationConditionPrintable.java | 6 +- .../configure/config/ConfigurationType.java | 10 +- .../config/ParserConfigurationAdapter.java | 69 ++++++----- .../PredefinedClassesConfiguration.java | 4 +- .../configure/config/ProxyConfiguration.java | 29 ++--- .../config/ResourceConfiguration.java | 53 +++++---- .../config/SerializationConfiguration.java | 34 +++--- ...ationConfigurationLambdaCapturingType.java | 12 +- .../SerializationConfigurationType.java | 10 +- .../configure/config/TypeConfiguration.java | 19 +-- .../ConditionalConfigurationComputer.java | 15 +-- .../ConditionalConfigurationPredicate.java | 8 +- .../svm/configure/trace/JniProcessor.java | 8 +- .../configure/trace/ReflectionProcessor.java | 12 +- .../trace/SerializationProcessor.java | 7 +- .../core/configure/ConditionalElement.java | 46 +------- .../ConfigurationConditionResolver.java} | 42 +++---- .../core/configure/ConfigurationParser.java | 16 ++- .../configure/ProxyConfigurationParser.java | 34 ++++-- .../ReflectionConfigurationParser.java | 87 +++++++------- ...ReflectionConfigurationParserDelegate.java | 46 ++++---- .../ResourceConfigurationParser.java | 34 ++++-- .../svm/core/configure/ResourcesRegistry.java | 43 ++----- .../SerializationConfigurationParser.java | 27 +++-- .../svm/core/jdk/JavaNetHttpFeature.java | 2 +- .../foreign/ForeignFunctionsFeature.java | 2 +- .../svm/hosted/ClassLoaderSupportImpl.java | 2 +- .../ConditionalConfigurationRegistry.java | 22 ++-- .../svm/hosted/ConfigurationTypeResolver.java | 4 - .../oracle/svm/hosted/ResourcesFeature.java | 42 +++---- .../config/ConfigurationParserUtils.java | 12 +- .../config/ReflectionRegistryAdapter.java | 71 ++++++----- .../svm/hosted/config/RegistryAdapter.java | 111 ++++++++---------- .../svm/hosted/jdk/JmxServerFeature.java | 2 +- .../svm/hosted/jni/JNIAccessFeature.java | 14 ++- .../reflect/NativeImageConditionResolver.java | 56 +++++++++ .../hosted/reflect/ReflectionDataBuilder.java | 52 ++++---- .../svm/hosted/reflect/ReflectionFeature.java | 7 +- .../reflect/proxy/DynamicProxyFeature.java | 11 +- .../hosted/reflect/proxy/ProxyRegistry.java | 34 +++--- .../serialize/SerializationFeature.java | 44 +++---- .../hosted/xml/XMLParsersRegistration.java | 34 +++--- .../svm/truffle/TruffleBaseFeature.java | 2 +- 53 files changed, 808 insertions(+), 673 deletions(-) create mode 100644 sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java rename substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/{jdk/localization/LocalizationFeature.java => configure/ConfigurationConditionResolver.java} (52%) create mode 100644 substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.java index 1e26a651c290..590952b8edf3 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,16 +40,16 @@ */ package org.graalvm.nativeimage.hosted; +import java.util.Arrays; +import java.util.Locale; +import java.util.Objects; + import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeResourceSupport; -import java.util.Arrays; -import java.util.Locale; -import java.util.Objects; - /** * This class can be used to register Java resources and ResourceBundles that should be accessible * at run time. @@ -96,7 +96,7 @@ public static void addResource(Module module, String resourcePath, byte[] resour */ public static void addResourceBundle(Module module, String baseBundleName, Locale[] locales) { Objects.requireNonNull(locales); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), + RuntimeResourceSupport.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), withModuleName(module, baseBundleName), Arrays.asList(locales)); } @@ -108,7 +108,7 @@ public static void addResourceBundle(Module module, String baseBundleName, Local * @since 22.3 */ public static void addResourceBundle(Module module, String bundleName) { - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), + RuntimeResourceSupport.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), withModuleName(module, bundleName)); } diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java index 64a12b19c7e9..09d2c4a42e99 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeSerialization.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -40,7 +40,6 @@ */ package org.graalvm.nativeimage.hosted; -import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; import org.graalvm.nativeimage.impl.ConfigurationCondition; @@ -73,7 +72,7 @@ public final class RuntimeSerialization { * @since 21.3 */ public static void registerIncludingAssociatedClasses(Class clazz) { - ImageSingletons.lookup(RuntimeSerializationSupport.class).registerIncludingAssociatedClasses(ConfigurationCondition.alwaysTrue(), clazz); + RuntimeSerializationSupport.singleton().registerIncludingAssociatedClasses(ConfigurationCondition.alwaysTrue(), clazz); } /** @@ -82,7 +81,7 @@ public static void registerIncludingAssociatedClasses(Class clazz) { * @since 21.3 */ public static void register(Class... classes) { - ImageSingletons.lookup(RuntimeSerializationSupport.class).register(ConfigurationCondition.alwaysTrue(), classes); + RuntimeSerializationSupport.singleton().register(ConfigurationCondition.alwaysTrue(), classes); } /** @@ -97,7 +96,7 @@ public static void register(Class... classes) { * @since 21.3 */ public static void registerWithTargetConstructorClass(Class clazz, Class customTargetConstructorClazz) { - ImageSingletons.lookup(RuntimeSerializationSupport.class).registerWithTargetConstructorClass(ConfigurationCondition.alwaysTrue(), clazz, customTargetConstructorClazz); + RuntimeSerializationSupport.singleton().registerWithTargetConstructorClass(ConfigurationCondition.alwaysTrue(), clazz, customTargetConstructorClazz); } /** @@ -108,7 +107,7 @@ public static void registerWithTargetConstructorClass(Class clazz, Class c * @since 22.3 */ public static void registerLambdaCapturingClass(Class lambdaCapturingClass) { - ImageSingletons.lookup(RuntimeSerializationSupport.class).registerLambdaCapturingClass(ConfigurationCondition.alwaysTrue(), lambdaCapturingClass); + RuntimeSerializationSupport.singleton().registerLambdaCapturingClass(ConfigurationCondition.alwaysTrue(), lambdaCapturingClass); } /** @@ -119,7 +118,7 @@ public static void registerLambdaCapturingClass(Class lambdaCapturingClass) { * @since 22.3 */ public static void registerProxyClass(Class... implementedInterfaces) { - ImageSingletons.lookup(RuntimeSerializationSupport.class).registerProxyClass(ConfigurationCondition.alwaysTrue(), implementedInterfaces); + RuntimeSerializationSupport.singleton().registerProxyClass(ConfigurationCondition.alwaysTrue(), implementedInterfaces); } private RuntimeSerialization() { 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 e089491291de..24ee15609829 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -42,32 +42,42 @@ import java.util.Objects; -public final class ConfigurationCondition implements Comparable { - private final String typeName; - private static final ConfigurationCondition OBJECT_REACHABLE = new ConfigurationCondition(Object.class.getTypeName()); +/** + * A condition that describes if a reflectively accessed element in Native Image is visible by the + * user. + *

+ * Currently, there is only one type of condition (typeReached) so this is a single + * 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. + */ +public final class ConfigurationCondition { + + /* Cached to save space: it is used as a marker for all non-conditional elements */ + private static final ConfigurationCondition JAVA_LANG_OBJECT_REACHED = new ConfigurationCondition(Object.class); public static ConfigurationCondition alwaysTrue() { - return OBJECT_REACHABLE; + return JAVA_LANG_OBJECT_REACHED; } - public static boolean isAlwaysTrue(ConfigurationCondition condition) { - return ConfigurationCondition.alwaysTrue().equals(condition); - } + private final Class type; - public static ConfigurationCondition create(String typeReachability) { - Objects.requireNonNull(typeReachability); - if (OBJECT_REACHABLE.typeName.equals(typeReachability)) { - return OBJECT_REACHABLE; + public static ConfigurationCondition create(Class type) { + if (JAVA_LANG_OBJECT_REACHED.getType().equals(type)) { + return JAVA_LANG_OBJECT_REACHED; } - return new ConfigurationCondition(typeReachability); + return new ConfigurationCondition(type); + } + + public boolean isAlwaysTrue() { + return ConfigurationCondition.alwaysTrue().equals(this); } - private ConfigurationCondition(String typeName) { - this.typeName = typeName; + private ConfigurationCondition(Class type) { + this.type = type; } - public String getTypeName() { - return typeName; + public Class getType() { + return type; } @Override @@ -79,21 +89,12 @@ public boolean equals(Object o) { return false; } ConfigurationCondition condition = (ConfigurationCondition) o; - return Objects.equals(typeName, condition.typeName); + return Objects.equals(type, condition.type); } @Override public int hashCode() { - return Objects.hash(typeName); + return Objects.hash(type); } - @Override - public int compareTo(ConfigurationCondition o) { - return this.typeName.compareTo(o.typeName); - } - - @Override - public String toString() { - return "[typeReachable: \"" + typeName + "\"" + "]"; - } } diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeResourceSupport.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeResourceSupport.java index 6147690f249c..b5f41d8655f5 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeResourceSupport.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeResourceSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -43,16 +43,24 @@ import java.util.Collection; import java.util.Locale; -public interface RuntimeResourceSupport { - void addResources(ConfigurationCondition condition, String pattern); +import org.graalvm.nativeimage.ImageSingletons; + +public interface RuntimeResourceSupport { + + @SuppressWarnings("unchecked") + static RuntimeResourceSupport singleton() { + return ImageSingletons.lookup(RuntimeResourceSupport.class); + } + + void addResources(C condition, String pattern); void addResource(Module module, String resourcePath); void injectResource(Module module, String resourcePath, byte[] resourceContent); - void ignoreResources(ConfigurationCondition condition, String pattern); + void ignoreResources(C condition, String pattern); - void addResourceBundles(ConfigurationCondition condition, String name); + void addResourceBundles(C condition, String name); - void addResourceBundles(ConfigurationCondition condition, String basename, Collection locales); + void addResourceBundles(C condition, String basename, Collection locales); } diff --git a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeSerializationSupport.java b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeSerializationSupport.java index 0d2d7352556c..6cecab043977 100644 --- a/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeSerializationSupport.java +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeSerializationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -44,25 +44,32 @@ import java.util.List; import java.util.stream.Collectors; -public interface RuntimeSerializationSupport { +import org.graalvm.nativeimage.ImageSingletons; - void registerIncludingAssociatedClasses(ConfigurationCondition condition, Class clazz); +public interface RuntimeSerializationSupport { - void register(ConfigurationCondition condition, Class... classes); + @SuppressWarnings("unchecked") + static RuntimeSerializationSupport singleton() { + return ImageSingletons.lookup(RuntimeSerializationSupport.class); + } + + void registerIncludingAssociatedClasses(C condition, Class clazz); + + void register(C condition, Class... classes); - void registerWithTargetConstructorClass(ConfigurationCondition condition, Class clazz, Class customTargetConstructorClazz); + void registerWithTargetConstructorClass(C condition, Class clazz, Class customTargetConstructorClazz); - void registerWithTargetConstructorClass(ConfigurationCondition condition, String className, String customTargetConstructorClassName); + void registerWithTargetConstructorClass(C condition, String className, String customTargetConstructorClassName); - void registerLambdaCapturingClass(ConfigurationCondition condition, String lambdaCapturingClassName); + void registerLambdaCapturingClass(C condition, String lambdaCapturingClassName); - default void registerLambdaCapturingClass(ConfigurationCondition condition, Class lambdaCapturingClass) { + default void registerLambdaCapturingClass(C condition, Class lambdaCapturingClass) { registerLambdaCapturingClass(condition, lambdaCapturingClass.getName()); } - void registerProxyClass(ConfigurationCondition condition, List implementedInterfaces); + void registerProxyClass(C condition, List implementedInterfaces); - default void registerProxyClass(ConfigurationCondition condition, Class... implementedInterfaces) { + default void registerProxyClass(C condition, Class... implementedInterfaces) { registerProxyClass(condition, Arrays.stream(implementedInterfaces).map(Class::getName).collect(Collectors.toList())); } } 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 new file mode 100644 index 000000000000..9dda1db6b546 --- /dev/null +++ b/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/UnresolvedConfigurationCondition.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.graalvm.nativeimage.impl; + +import java.util.Objects; + +/** + * This is an unresolved version of the {@link ConfigurationCondition} used only during parsing. + */ +public class UnresolvedConfigurationCondition implements Comparable { + private final String typeName; + private static final UnresolvedConfigurationCondition JAVA_LANG_OBJECT_REACHED = new UnresolvedConfigurationCondition(Object.class.getTypeName()); + + public static UnresolvedConfigurationCondition create(String typeName) { + Objects.requireNonNull(typeName); + if (JAVA_LANG_OBJECT_REACHED.getTypeName().equals(typeName)) { + return JAVA_LANG_OBJECT_REACHED; + } + return new UnresolvedConfigurationCondition(typeName); + } + + protected UnresolvedConfigurationCondition(String typeName) { + this.typeName = typeName; + } + + public static UnresolvedConfigurationCondition alwaysTrue() { + return JAVA_LANG_OBJECT_REACHED; + } + + public String getTypeName() { + return typeName; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + UnresolvedConfigurationCondition condition = (UnresolvedConfigurationCondition) o; + return Objects.equals(typeName, condition.typeName); + } + + @Override + public int hashCode() { + return Objects.hash(typeName); + } + + @Override + public String toString() { + return "[\"typeReachable\": \"" + typeName + "\"" + "]"; + } + + @Override + public int compareTo(UnresolvedConfigurationCondition c) { + return this.typeName.compareTo(c.typeName); + } + + public boolean isAlwaysTrue() { + return typeName.equals(JAVA_LANG_OBJECT_REACHED.getTypeName()); + } +} diff --git a/substratevm/mx.substratevm/mx_substratevm.py b/substratevm/mx.substratevm/mx_substratevm.py index fa896c41fdd9..4d24f352b79d 100644 --- a/substratevm/mx.substratevm/mx_substratevm.py +++ b/substratevm/mx.substratevm/mx_substratevm.py @@ -639,7 +639,7 @@ def dummy_harness(test_deps, vm_launcher, vm_args): if not preserve_image: mx.rmtree(junit_test_dir) -_mask_str = '#' +_mask_str = '$mask$' def _mask(arg, arg_list): diff --git a/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/OmitPreviousConfigTests.java b/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/OmitPreviousConfigTests.java index 38c5440b0feb..361845eeaf99 100644 --- a/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/OmitPreviousConfigTests.java +++ b/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/OmitPreviousConfigTests.java @@ -35,7 +35,7 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import org.junit.Assert; import org.junit.Test; @@ -142,8 +142,8 @@ private static void doTestTypeConfig(TypeConfiguration typeConfig) { } private static void doTestExpectedMissingTypes(TypeConfiguration typeConfig) { - Assert.assertNull(typeConfig.get(ConfigurationCondition.alwaysTrue(), "FlagTestA")); - Assert.assertNull(typeConfig.get(ConfigurationCondition.alwaysTrue(), "FlagTestB")); + Assert.assertNull(typeConfig.get(UnresolvedConfigurationCondition.alwaysTrue(), "FlagTestA")); + Assert.assertNull(typeConfig.get(UnresolvedConfigurationCondition.alwaysTrue(), "FlagTestB")); } private static void doTestTypeFlags(TypeConfiguration typeConfig) { @@ -180,7 +180,7 @@ private static void doTestMethods(TypeConfiguration typeConfig) { } private static void doTestProxyConfig(ProxyConfiguration proxyConfig) { - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); Assert.assertFalse(proxyConfig.contains(condition, "testProxySeenA", "testProxySeenB", "testProxySeenC")); Assert.assertTrue(proxyConfig.contains(condition, "testProxyUnseen")); } @@ -189,19 +189,19 @@ private static void doTestResourceConfig(ResourceConfiguration resourceConfig) { Assert.assertFalse(resourceConfig.anyResourceMatches("seenResource.txt")); Assert.assertTrue(resourceConfig.anyResourceMatches("unseenResource.txt")); - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); Assert.assertFalse(resourceConfig.anyBundleMatches(condition, "seenBundle")); Assert.assertTrue(resourceConfig.anyBundleMatches(condition, "unseenBundle")); } private static void doTestSerializationConfig(SerializationConfiguration serializationConfig) { - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); Assert.assertFalse(serializationConfig.contains(condition, "seenType", null)); Assert.assertTrue(serializationConfig.contains(condition, "unseenType", null)); } private static ConfigurationType getConfigTypeOrFail(TypeConfiguration typeConfig, String typeName) { - ConfigurationType type = typeConfig.get(ConfigurationCondition.alwaysTrue(), typeName); + ConfigurationType type = typeConfig.get(UnresolvedConfigurationCondition.alwaysTrue(), typeName); Assert.assertNotNull(type); return type; } @@ -260,11 +260,11 @@ Map getMethodsMap(Configura } void populateConfig() { - ConfigurationType oldType = new ConfigurationType(ConfigurationCondition.alwaysTrue(), getTypeName()); + ConfigurationType oldType = new ConfigurationType(UnresolvedConfigurationCondition.alwaysTrue(), getTypeName()); setFlags(oldType); previousConfig.add(oldType); - ConfigurationType newType = new ConfigurationType(ConfigurationCondition.alwaysTrue(), getTypeName()); + ConfigurationType newType = new ConfigurationType(UnresolvedConfigurationCondition.alwaysTrue(), getTypeName()); for (Map.Entry methodEntry : methodsThatMustExist.entrySet()) { newType.addMethod(methodEntry.getKey().getName(), methodEntry.getKey().getInternalSignature(), methodEntry.getValue()); } @@ -297,7 +297,7 @@ void doTest() { TypeConfiguration currentConfigWithoutPrevious = currentConfig.copyAndSubtract(previousConfig); String name = getTypeName(); - ConfigurationType configurationType = currentConfigWithoutPrevious.get(ConfigurationCondition.alwaysTrue(), name); + ConfigurationType configurationType = currentConfigWithoutPrevious.get(UnresolvedConfigurationCondition.alwaysTrue(), name); if (methodsThatMustExist.size() == 0) { Assert.assertNull("Generated configuration type " + name + " exists. Expected it to be cleared as it is empty.", configurationType); } else { diff --git a/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/ResourceConfigurationTest.java b/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/ResourceConfigurationTest.java index d4007bbee5e6..4bb6c9ae0ca0 100644 --- a/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/ResourceConfigurationTest.java +++ b/substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/ResourceConfigurationTest.java @@ -33,11 +33,12 @@ import java.util.List; import java.util.Locale; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import org.junit.Assert; import org.junit.Test; import com.oracle.svm.configure.config.ResourceConfiguration; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ResourceConfigurationParser; import com.oracle.svm.core.configure.ResourcesRegistry; import com.oracle.svm.core.util.VMError; @@ -48,7 +49,7 @@ public class ResourceConfigurationTest { @Test public void anyResourceMatches() { ResourceConfiguration rc = new ResourceConfiguration(); - ConfigurationCondition defaultCond = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition defaultCond = UnresolvedConfigurationCondition.alwaysTrue(); rc.addResourcePattern(defaultCond, ".*/Resource.*txt$"); Assert.assertTrue(rc.anyResourceMatches("com/my/app/Resource0.txt")); @@ -67,7 +68,7 @@ public void anyResourceMatches() { @Test public void printJson() { ResourceConfiguration rc = new ResourceConfiguration(); - ConfigurationCondition defaultCond = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition defaultCond = UnresolvedConfigurationCondition.alwaysTrue(); rc.addResourcePattern(defaultCond, ".*/Resource.*txt$"); rc.ignoreResourcePattern(defaultCond, ".*/Resource2.txt$"); PipedWriter pw = new PipedWriter(); @@ -87,10 +88,10 @@ public void printJson() { List addedResources = new LinkedList<>(); List ignoredResources = new LinkedList<>(); - ResourcesRegistry registry = new ResourcesRegistry() { + ResourcesRegistry registry = new ResourcesRegistry<>() { @Override - public void addResources(ConfigurationCondition condition, String pattern) { + public void addResources(UnresolvedConfigurationCondition condition, String pattern) { addedResources.add(pattern); } @@ -104,26 +105,26 @@ public void injectResource(Module module, String resourcePath, byte[] resourceCo } @Override - public void ignoreResources(ConfigurationCondition condition, String pattern) { + public void ignoreResources(UnresolvedConfigurationCondition condition, String pattern) { ignoredResources.add(pattern); } @Override - public void addResourceBundles(ConfigurationCondition condition, String name) { + public void addResourceBundles(UnresolvedConfigurationCondition condition, String name) { } @Override - public void addResourceBundles(ConfigurationCondition condition, String basename, Collection locales) { + public void addResourceBundles(UnresolvedConfigurationCondition condition, String basename, Collection locales) { } @Override - public void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className) { + public void addClassBasedResourceBundle(UnresolvedConfigurationCondition condition, String basename, String className) { } }; - ResourceConfigurationParser rcp = new ResourceConfigurationParser(registry, true); + ResourceConfigurationParser rcp = new ResourceConfigurationParser<>(ConfigurationConditionResolver.identityResolver(), registry, true); writerThread.start(); rcp.parseAndRegister(pr); @@ -132,8 +133,7 @@ public void addClassBasedResourceBundle(ConfigurationCondition condition, String Assert.assertTrue(addedResources.contains(".*/Resource.*txt$")); Assert.assertTrue(ignoredResources.contains(".*/Resource2.txt$")); } catch (IOException | InterruptedException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); + throw new RuntimeException(e); } } } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ConfigurationBase.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ConfigurationBase.java index 26a7c7a596da..80f68175be98 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ConfigurationBase.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/ConfigurationBase.java @@ -26,9 +26,10 @@ import java.util.function.Consumer; -import com.oracle.svm.core.util.json.JsonPrintable; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; + import com.oracle.svm.core.configure.ConfigurationParser; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import com.oracle.svm.core.util.json.JsonPrintable; public abstract class ConfigurationBase, P> implements JsonPrintable { @@ -38,7 +39,7 @@ public abstract class ConfigurationBase, P> im protected abstract void merge(T other); - public abstract void mergeConditional(ConfigurationCondition condition, T other); + public abstract void mergeConditional(UnresolvedConfigurationCondition condition, T other); protected abstract void subtract(T other); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationConditionPrintable.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationConditionPrintable.java index 8be1eefc6620..9d2ab29abaa1 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationConditionPrintable.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationConditionPrintable.java @@ -29,13 +29,13 @@ import java.io.IOException; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.core.util.json.JsonWriter; final class ConfigurationConditionPrintable { - static void printConditionAttribute(ConfigurationCondition condition, JsonWriter writer) throws IOException { - if (!condition.equals(ConfigurationCondition.alwaysTrue())) { + static void printConditionAttribute(UnresolvedConfigurationCondition condition, JsonWriter writer) throws IOException { + if (!condition.isAlwaysTrue()) { writer.quote(CONDITIONAL_KEY).append(":{"); writer.quote(TYPE_REACHABLE_KEY).append(':').quote(condition.getTypeName()); writer.append("},").newline(); diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationType.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationType.java index 4d90efc89f14..bfce9e7d7f64 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationType.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ConfigurationType.java @@ -35,7 +35,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberAccessibility; import com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberDeclaration; @@ -85,7 +85,7 @@ static ConfigurationType copyAndMerge(ConfigurationType type, ConfigurationType return copy; } - private final ConfigurationCondition condition; + private final UnresolvedConfigurationCondition condition; private final String qualifiedJavaName; private Map fields; @@ -105,14 +105,14 @@ static ConfigurationType copyAndMerge(ConfigurationType type, ConfigurationType private ConfigurationMemberAccessibility allDeclaredConstructorsAccess = ConfigurationMemberAccessibility.NONE; private ConfigurationMemberAccessibility allPublicConstructorsAccess = ConfigurationMemberAccessibility.NONE; - public ConfigurationType(ConfigurationCondition condition, String qualifiedJavaName) { + public ConfigurationType(UnresolvedConfigurationCondition condition, String qualifiedJavaName) { assert qualifiedJavaName.indexOf('/') == -1 : "Requires qualified Java name, not internal representation"; assert !qualifiedJavaName.startsWith("[") : "Requires Java source array syntax, for example java.lang.String[]"; this.condition = condition; this.qualifiedJavaName = qualifiedJavaName; } - ConfigurationType(ConfigurationType other, ConfigurationCondition condition) { + ConfigurationType(ConfigurationType other, UnresolvedConfigurationCondition condition) { // Our object is not yet published, so it is sufficient to take only the other object's lock synchronized (other) { qualifiedJavaName = other.qualifiedJavaName; @@ -523,7 +523,7 @@ private static Map maybeRemove(Map fromMap, Consumer { +public class ParserConfigurationAdapter implements ReflectionConfigurationParserDelegate { private final TypeConfiguration configuration; @@ -42,114 +43,128 @@ public ParserConfigurationAdapter(TypeConfiguration configuration) { } @Override - public TypeResult resolveCondition(String typeName) { - return TypeResult.forType(typeName, ConfigurationCondition.create(typeName)); - } - - @Override - public TypeResult resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) { + public TypeResult resolveType(UnresolvedConfigurationCondition condition, String typeName, boolean allowPrimitives) { ConfigurationType type = configuration.get(condition, typeName); ConfigurationType result = type != null ? type : new ConfigurationType(condition, typeName); return TypeResult.forType(typeName, result); } @Override - public void registerType(ConfigurationType type) { + public void registerType(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); configuration.add(type); } @Override - public void registerField(ConfigurationType type, String fieldName, boolean finalButWritable) { + public void registerField(UnresolvedConfigurationCondition condition, ConfigurationType type, String fieldName, boolean finalButWritable) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.addField(fieldName, ConfigurationMemberDeclaration.PRESENT, finalButWritable); } @Override - public boolean registerAllMethodsWithName(boolean queriedOnly, ConfigurationType type, String methodName) { + public boolean registerAllMethodsWithName(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type, String methodName) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.addMethodsWithName(methodName, ConfigurationMemberDeclaration.PRESENT, queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); return true; } @Override - public boolean registerAllConstructors(boolean queriedOnly, ConfigurationType type) { + public boolean registerAllConstructors(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.addMethodsWithName(ConfigurationMethod.CONSTRUCTOR_NAME, ConfigurationMemberDeclaration.PRESENT, queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); return true; } @Override - public void registerUnsafeAllocated(ConfigurationType type) { + public void registerUnsafeAllocated(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is here part of the type"); type.setUnsafeAllocated(); } @Override - public void registerMethod(boolean queriedOnly, ConfigurationType type, String methodName, List methodParameterTypes) { + public void registerMethod(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type, String methodName, List methodParameterTypes) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.addMethod(methodName, ConfigurationMethod.toInternalParamsSignature(methodParameterTypes), ConfigurationMemberDeclaration.PRESENT, queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } @Override - public void registerConstructor(boolean queriedOnly, ConfigurationType type, List methodParameterTypes) { + public void registerConstructor(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type, List methodParameterTypes) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.addMethod(ConfigurationMethod.CONSTRUCTOR_NAME, ConfigurationMethod.toInternalParamsSignature(methodParameterTypes), ConfigurationMemberDeclaration.PRESENT, queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } @Override - public void registerPublicClasses(ConfigurationType type) { + public void registerPublicClasses(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllPublicClasses(); } @Override - public void registerDeclaredClasses(ConfigurationType type) { + public void registerDeclaredClasses(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllDeclaredClasses(); } @Override - public void registerRecordComponents(ConfigurationType type) { + public void registerRecordComponents(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllRecordComponents(); } @Override - public void registerPermittedSubclasses(ConfigurationType type) { + public void registerPermittedSubclasses(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllPermittedSubclasses(); } @Override - public void registerNestMembers(ConfigurationType type) { + public void registerNestMembers(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllNestMembers(); } @Override - public void registerSigners(ConfigurationType type) { + public void registerSigners(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllSigners(); } @Override - public void registerPublicFields(ConfigurationType type) { + public void registerPublicFields(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllPublicFields(); } @Override - public void registerDeclaredFields(ConfigurationType type) { + public void registerDeclaredFields(UnresolvedConfigurationCondition condition, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllDeclaredFields(); } @Override - public void registerPublicMethods(boolean queriedOnly, ConfigurationType type) { + public void registerPublicMethods(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllPublicMethods(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } @Override - public void registerDeclaredMethods(boolean queriedOnly, ConfigurationType type) { + public void registerDeclaredMethods(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllDeclaredMethods(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } @Override - public void registerPublicConstructors(boolean queriedOnly, ConfigurationType type) { + public void registerPublicConstructors(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllPublicConstructors(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } @Override - public void registerDeclaredConstructors(boolean queriedOnly, ConfigurationType type) { + public void registerDeclaredConstructors(UnresolvedConfigurationCondition condition, boolean queriedOnly, ConfigurationType type) { + VMError.guarantee(condition.equals(type.getCondition()), "condition is already a part of the type"); type.setAllDeclaredConstructors(queriedOnly ? ConfigurationMemberAccessibility.QUERIED : ConfigurationMemberAccessibility.ACCESSED); } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/PredefinedClassesConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/PredefinedClassesConfiguration.java index 40229ed4648f..502a16a5f462 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/PredefinedClassesConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/PredefinedClassesConfiguration.java @@ -35,13 +35,13 @@ import java.util.concurrent.ConcurrentMap; import com.oracle.svm.core.configure.ConfigurationParser; -import org.graalvm.nativeimage.impl.ConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; import com.oracle.svm.core.util.json.JsonWriter; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.PredefinedClassesConfigurationParser; import com.oracle.svm.core.hub.PredefinedClassesSupport; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; public final class PredefinedClassesConfiguration extends ConfigurationBase { private final Path[] classDestinationDirs; @@ -85,7 +85,7 @@ protected void removeIf(Predicate predicate) { } @Override - public void mergeConditional(ConfigurationCondition condition, PredefinedClassesConfiguration other) { + public void mergeConditional(UnresolvedConfigurationCondition condition, PredefinedClassesConfiguration other) { /* Not implemented with conditions yet */ classes.putAll(other.classes); } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ProxyConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ProxyConfiguration.java index 9859a20d9e55..dc4fa96686db 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ProxyConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ProxyConfiguration.java @@ -31,13 +31,14 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import com.oracle.svm.core.configure.ConfigurationParser; -import com.oracle.svm.core.configure.ProxyConfigurationParser; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; -import com.oracle.svm.core.util.json.JsonWriter; import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; +import com.oracle.svm.core.configure.ConfigurationParser; +import com.oracle.svm.core.configure.ProxyConfigurationParser; +import com.oracle.svm.core.util.json.JsonWriter; public final class ProxyConfiguration extends ConfigurationBase { private final Set>> interfaceLists = ConcurrentHashMap.newKeySet(); @@ -47,7 +48,7 @@ public ProxyConfiguration() { public ProxyConfiguration(ProxyConfiguration other) { for (ConditionalElement> interfaceList : other.interfaceLists) { - interfaceLists.add(new ConditionalElement<>(interfaceList.getCondition(), new ArrayList<>(interfaceList.getElement()))); + interfaceLists.add(new ConditionalElement<>(interfaceList.condition(), new ArrayList<>(interfaceList.element()))); } } @@ -59,7 +60,7 @@ public ProxyConfiguration copy() { @Override protected void merge(ProxyConfiguration other) { for (ConditionalElement> interfaceList : other.interfaceLists) { - interfaceLists.add(new ConditionalElement<>(interfaceList.getCondition(), new ArrayList<>(interfaceList.getElement()))); + interfaceLists.add(new ConditionalElement<>(interfaceList.condition(), new ArrayList<>(interfaceList.element()))); } } @@ -79,21 +80,21 @@ public void subtract(ProxyConfiguration other) { } @Override - public void mergeConditional(ConfigurationCondition condition, ProxyConfiguration other) { + public void mergeConditional(UnresolvedConfigurationCondition condition, ProxyConfiguration other) { for (ConditionalElement> interfaceList : other.interfaceLists) { - add(condition, new ArrayList<>(interfaceList.getElement())); + add(condition, new ArrayList<>(interfaceList.element())); } } - public void add(ConfigurationCondition condition, List interfaceList) { + public void add(UnresolvedConfigurationCondition condition, List interfaceList) { interfaceLists.add(new ConditionalElement<>(condition, interfaceList)); } - public boolean contains(ConfigurationCondition condition, List interfaceList) { + public boolean contains(UnresolvedConfigurationCondition condition, List interfaceList) { return interfaceLists.contains(new ConditionalElement<>(condition, interfaceList)); } - public boolean contains(ConfigurationCondition condition, String... interfaces) { + public boolean contains(UnresolvedConfigurationCondition condition, String... interfaces) { return contains(condition, Arrays.asList(interfaces)); } @@ -113,10 +114,10 @@ public static void printProxyInterfaces(JsonWriter writer, List> list : lists) { writer.append(prefix).newline(); writer.append('{').indent().newline(); - ConfigurationConditionPrintable.printConditionAttribute(list.getCondition(), writer); + ConfigurationConditionPrintable.printConditionAttribute(list.condition(), writer); writer.quote("interfaces").append(":").append('['); String typePrefix = ""; - for (String type : list.getElement()) { + for (String type : list.element()) { writer.append(typePrefix).quote(type); typePrefix = ","; } @@ -130,7 +131,7 @@ public static void printProxyInterfaces(JsonWriter writer, List(ConfigurationConditionResolver.identityResolver(), true, (cond, interfaces) -> interfaceLists.add(new ConditionalElement<>(cond, interfaces))); } @Override diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java index c3aae5d266a8..c2dde84c72c6 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java @@ -34,10 +34,11 @@ import java.util.concurrent.ConcurrentMap; import java.util.regex.Pattern; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationParser; import com.oracle.svm.core.configure.ResourceConfigurationParser; import com.oracle.svm.core.configure.ResourcesRegistry; @@ -47,7 +48,7 @@ public final class ResourceConfiguration extends ConfigurationBase { - public static class ParserAdapter implements ResourcesRegistry { + public static class ParserAdapter implements ResourcesRegistry { private final ResourceConfiguration configuration; @@ -56,7 +57,7 @@ public static class ParserAdapter implements ResourcesRegistry { } @Override - public void addResources(ConfigurationCondition condition, String pattern) { + public void addResources(UnresolvedConfigurationCondition condition, String pattern) { configuration.addResourcePattern(condition, pattern); } @@ -71,33 +72,33 @@ public void injectResource(Module module, String resourcePath, byte[] resourceCo } @Override - public void ignoreResources(ConfigurationCondition condition, String pattern) { + public void ignoreResources(UnresolvedConfigurationCondition condition, String pattern) { configuration.ignoreResourcePattern(condition, pattern); } @Override - public void addResourceBundles(ConfigurationCondition condition, String baseName) { + public void addResourceBundles(UnresolvedConfigurationCondition condition, String baseName) { configuration.addBundle(condition, baseName); } @Override - public void addResourceBundles(ConfigurationCondition condition, String basename, Collection locales) { + public void addResourceBundles(UnresolvedConfigurationCondition condition, String basename, Collection locales) { configuration.addBundle(condition, basename, locales); } @Override - public void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className) { + public void addClassBasedResourceBundle(UnresolvedConfigurationCondition condition, String basename, String className) { configuration.addClassResourceBundle(condition, basename, className); } } public static final class BundleConfiguration { - public final ConfigurationCondition condition; + public final UnresolvedConfigurationCondition condition; public final String baseName; public final Set locales = ConcurrentHashMap.newKeySet(); public final Set classNames = ConcurrentHashMap.newKeySet(); - private BundleConfiguration(ConfigurationCondition condition, String baseName) { + private BundleConfiguration(UnresolvedConfigurationCondition condition, String baseName) { this.condition = condition; this.baseName = baseName; } @@ -157,47 +158,47 @@ protected void removeIf(Predicate predicate) { } @Override - public void mergeConditional(ConfigurationCondition condition, ResourceConfiguration other) { + public void mergeConditional(UnresolvedConfigurationCondition condition, ResourceConfiguration other) { for (Map.Entry, Pattern> entry : other.addedResources.entrySet()) { - addedResources.put(new ConditionalElement<>(condition, entry.getKey().getElement()), entry.getValue()); + addedResources.put(new ConditionalElement<>(condition, entry.getKey().element()), entry.getValue()); } for (Map.Entry, Pattern> entry : other.ignoredResources.entrySet()) { - ignoredResources.put(new ConditionalElement<>(condition, entry.getKey().getElement()), entry.getValue()); + ignoredResources.put(new ConditionalElement<>(condition, entry.getKey().element()), entry.getValue()); } for (Map.Entry, BundleConfiguration> entry : other.bundles.entrySet()) { - bundles.put(new ConditionalElement<>(condition, entry.getKey().getElement()), new BundleConfiguration(entry.getValue())); + bundles.put(new ConditionalElement<>(condition, entry.getKey().element()), new BundleConfiguration(entry.getValue())); } } - public void addResourcePattern(ConfigurationCondition condition, String pattern) { - addedResources.computeIfAbsent(new ConditionalElement<>(condition, pattern), p -> Pattern.compile(p.getElement())); + public void addResourcePattern(UnresolvedConfigurationCondition condition, String pattern) { + addedResources.computeIfAbsent(new ConditionalElement<>(condition, pattern), p -> Pattern.compile(p.element())); } - public void ignoreResourcePattern(ConfigurationCondition condition, String pattern) { - ignoredResources.computeIfAbsent(new ConditionalElement<>(condition, pattern), p -> Pattern.compile(p.getElement())); + public void ignoreResourcePattern(UnresolvedConfigurationCondition condition, String pattern) { + ignoredResources.computeIfAbsent(new ConditionalElement<>(condition, pattern), p -> Pattern.compile(p.element())); } - public void addBundle(ConfigurationCondition condition, String basename, Collection locales) { + public void addBundle(UnresolvedConfigurationCondition condition, String basename, Collection locales) { BundleConfiguration config = getOrCreateBundleConfig(condition, basename); for (Locale locale : locales) { config.locales.add(locale.toLanguageTag()); } } - private void addBundle(ConfigurationCondition condition, String baseName) { + private void addBundle(UnresolvedConfigurationCondition condition, String baseName) { getOrCreateBundleConfig(condition, baseName); } - private void addClassResourceBundle(ConfigurationCondition condition, String basename, String className) { + private void addClassResourceBundle(UnresolvedConfigurationCondition condition, String basename, String className) { getOrCreateBundleConfig(condition, basename).classNames.add(className); } - public void addBundle(ConfigurationCondition condition, String baseName, String queriedLocale) { + public void addBundle(UnresolvedConfigurationCondition condition, String baseName, String queriedLocale) { BundleConfiguration config = getOrCreateBundleConfig(condition, baseName); config.locales.add(queriedLocale); } - private BundleConfiguration getOrCreateBundleConfig(ConfigurationCondition condition, String baseName) { + private BundleConfiguration getOrCreateBundleConfig(UnresolvedConfigurationCondition condition, String baseName) { ConditionalElement key = new ConditionalElement<>(condition, baseName); return bundles.computeIfAbsent(key, cond -> new BundleConfiguration(condition, baseName)); } @@ -220,7 +221,7 @@ public boolean anyResourceMatches(String s) { return false; } - public boolean anyBundleMatches(ConfigurationCondition condition, String bundleName) { + public boolean anyBundleMatches(UnresolvedConfigurationCondition condition, String bundleName) { return bundles.containsKey(new ConditionalElement<>(condition, bundleName)); } @@ -243,7 +244,7 @@ public void printJson(JsonWriter writer) throws IOException { @Override public ConfigurationParser createParser() { - return new ResourceConfigurationParser(new ResourceConfiguration.ParserAdapter(this), true); + return new ResourceConfigurationParser<>(ConfigurationConditionResolver.identityResolver(), new ResourceConfiguration.ParserAdapter(this), true); } private static void printResourceBundle(BundleConfiguration config, JsonWriter writer) throws IOException { @@ -268,8 +269,8 @@ public boolean isEmpty() { private static void conditionalElementJson(ConditionalElement p, JsonWriter w, String elementName) throws IOException { w.append('{').indent().newline(); - ConfigurationConditionPrintable.printConditionAttribute(p.getCondition(), w); - w.quote(elementName).append(':').quote(p.getElement()); + ConfigurationConditionPrintable.printConditionAttribute(p.condition(), w); + w.quote(elementName).append(':').quote(p.element()); w.unindent().newline().append('}'); } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfiguration.java index cf8403034572..6ea621b8f4e9 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfiguration.java @@ -32,19 +32,21 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import jdk.graal.compiler.java.LambdaUtils; -import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeSerializationSupport; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; -import com.oracle.svm.core.util.json.JsonPrintable; -import com.oracle.svm.core.util.json.JsonWriter; import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationParser; import com.oracle.svm.core.configure.SerializationConfigurationParser; +import com.oracle.svm.core.util.json.JsonPrintable; +import com.oracle.svm.core.util.json.JsonWriter; + +import jdk.graal.compiler.java.LambdaUtils; public final class SerializationConfiguration extends ConfigurationBase - implements RuntimeSerializationSupport { + implements RuntimeSerializationSupport { private final Set serializations = ConcurrentHashMap.newKeySet(); private final Set lambdaSerializationCapturingTypes = ConcurrentHashMap.newKeySet(); @@ -95,13 +97,13 @@ protected void removeIf(Predicate predicate) { } @Override - public void mergeConditional(ConfigurationCondition condition, SerializationConfiguration other) { + public void mergeConditional(UnresolvedConfigurationCondition condition, SerializationConfiguration other) { for (SerializationConfigurationType type : other.serializations) { serializations.add(new SerializationConfigurationType(condition, type.getQualifiedJavaName(), type.getQualifiedCustomTargetConstructorJavaName())); } } - public boolean contains(ConfigurationCondition condition, String serializationTargetClass, String customTargetConstructorClass) { + public boolean contains(UnresolvedConfigurationCondition condition, String serializationTargetClass, String customTargetConstructorClass) { return serializations.contains(createConfigurationType(condition, serializationTargetClass, customTargetConstructorClass)) || lambdaSerializationCapturingTypes.contains(createLambdaCapturingClassConfigurationType(condition, serializationTargetClass)); } @@ -124,7 +126,7 @@ public void printJson(JsonWriter writer) throws IOException { @Override public ConfigurationParser createParser() { - return new SerializationConfigurationParser(this, true); + return new SerializationConfigurationParser<>(ConfigurationConditionResolver.identityResolver(), this, true); } private void printProxies(JsonWriter writer) throws IOException { @@ -154,34 +156,34 @@ private static void printSerializationTypes(List serial } @Override - public void registerIncludingAssociatedClasses(ConfigurationCondition condition, Class clazz) { + public void registerIncludingAssociatedClasses(UnresolvedConfigurationCondition condition, Class clazz) { register(condition, clazz); } @Override - public void register(ConfigurationCondition condition, Class... classes) { + public void register(UnresolvedConfigurationCondition condition, Class... classes) { for (Class clazz : classes) { registerWithTargetConstructorClass(condition, clazz, null); } } @Override - public void registerWithTargetConstructorClass(ConfigurationCondition condition, Class clazz, Class customTargetConstructorClazz) { + public void registerWithTargetConstructorClass(UnresolvedConfigurationCondition condition, Class clazz, Class customTargetConstructorClazz) { registerWithTargetConstructorClass(condition, clazz.getName(), customTargetConstructorClazz == null ? null : customTargetConstructorClazz.getName()); } @Override - public void registerWithTargetConstructorClass(ConfigurationCondition condition, String className, String customTargetConstructorClassName) { + public void registerWithTargetConstructorClass(UnresolvedConfigurationCondition condition, String className, String customTargetConstructorClassName) { serializations.add(createConfigurationType(condition, className, customTargetConstructorClassName)); } @Override - public void registerLambdaCapturingClass(ConfigurationCondition condition, String lambdaCapturingClassName) { + public void registerLambdaCapturingClass(UnresolvedConfigurationCondition condition, String lambdaCapturingClassName) { lambdaSerializationCapturingTypes.add(createLambdaCapturingClassConfigurationType(condition, lambdaCapturingClassName.split(LambdaUtils.LAMBDA_SPLIT_PATTERN)[0])); } @Override - public void registerProxyClass(ConfigurationCondition condition, List implementedInterfaces) { + public void registerProxyClass(UnresolvedConfigurationCondition condition, List implementedInterfaces) { interfaceListsSerializableProxies.add(new ConditionalElement<>(condition, implementedInterfaces)); } @@ -190,13 +192,13 @@ public boolean isEmpty() { return serializations.isEmpty() && lambdaSerializationCapturingTypes.isEmpty() || interfaceListsSerializableProxies.isEmpty(); } - private static SerializationConfigurationType createConfigurationType(ConfigurationCondition condition, String className, String customTargetConstructorClassName) { + private static SerializationConfigurationType createConfigurationType(UnresolvedConfigurationCondition condition, String className, String customTargetConstructorClassName) { String convertedClassName = SignatureUtil.toInternalClassName(className); String convertedCustomTargetConstructorClassName = customTargetConstructorClassName == null ? null : SignatureUtil.toInternalClassName(customTargetConstructorClassName); return new SerializationConfigurationType(condition, convertedClassName, convertedCustomTargetConstructorClassName); } - private static SerializationConfigurationLambdaCapturingType createLambdaCapturingClassConfigurationType(ConfigurationCondition condition, String className) { + private static SerializationConfigurationLambdaCapturingType createLambdaCapturingClassConfigurationType(UnresolvedConfigurationCondition condition, String className) { String convertedClassName = SignatureUtil.toInternalClassName(className); return new SerializationConfigurationLambdaCapturingType(condition, convertedClassName); } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationLambdaCapturingType.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationLambdaCapturingType.java index 4cf0e83b2a65..1ab9ffe8a241 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationLambdaCapturingType.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationLambdaCapturingType.java @@ -28,17 +28,17 @@ import java.util.Comparator; import java.util.Objects; -import com.oracle.svm.core.util.json.JsonPrintable; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; -import com.oracle.svm.core.util.json.JsonWriter; import com.oracle.svm.core.configure.SerializationConfigurationParser; +import com.oracle.svm.core.util.json.JsonPrintable; +import com.oracle.svm.core.util.json.JsonWriter; public class SerializationConfigurationLambdaCapturingType implements JsonPrintable { - private final ConfigurationCondition condition; + private final UnresolvedConfigurationCondition condition; private final String qualifiedJavaName; - public SerializationConfigurationLambdaCapturingType(ConfigurationCondition condition, String qualifiedJavaName) { + public SerializationConfigurationLambdaCapturingType(UnresolvedConfigurationCondition condition, String qualifiedJavaName) { assert qualifiedJavaName.indexOf('/') == -1 : "Requires qualified Java name, not the internal representation"; Objects.requireNonNull(condition); this.condition = condition; @@ -46,7 +46,7 @@ public SerializationConfigurationLambdaCapturingType(ConfigurationCondition cond this.qualifiedJavaName = qualifiedJavaName; } - public ConfigurationCondition getCondition() { + public UnresolvedConfigurationCondition getCondition() { return condition; } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationType.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationType.java index 33744a735875..21f5d6f0bbc4 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationType.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/SerializationConfigurationType.java @@ -28,18 +28,18 @@ import java.util.Comparator; import java.util.Objects; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; +import com.oracle.svm.core.configure.SerializationConfigurationParser; import com.oracle.svm.core.util.json.JsonPrintable; import com.oracle.svm.core.util.json.JsonWriter; -import com.oracle.svm.core.configure.SerializationConfigurationParser; public class SerializationConfigurationType implements JsonPrintable, Comparable { - private final ConfigurationCondition condition; + private final UnresolvedConfigurationCondition condition; private final String qualifiedJavaName; private final String qualifiedCustomTargetConstructorJavaName; - public SerializationConfigurationType(ConfigurationCondition condition, String qualifiedJavaName, String qualifiedCustomTargetConstructorJavaName) { + public SerializationConfigurationType(UnresolvedConfigurationCondition condition, String qualifiedJavaName, String qualifiedCustomTargetConstructorJavaName) { assert qualifiedJavaName.indexOf('/') == -1 : "Requires qualified Java name, not the internal representation"; assert !qualifiedJavaName.startsWith("[") : "Requires Java source array syntax, for example java.lang.String[]"; assert qualifiedCustomTargetConstructorJavaName == null || qualifiedCustomTargetConstructorJavaName.indexOf('/') == -1 : "Requires qualified Java name, not internal representation"; @@ -59,7 +59,7 @@ public String getQualifiedCustomTargetConstructorJavaName() { return qualifiedCustomTargetConstructorJavaName; } - public ConfigurationCondition getCondition() { + public UnresolvedConfigurationCondition getCondition() { return condition; } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/TypeConfiguration.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/TypeConfiguration.java index b90efed5dfdb..b9aa5d048f1b 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/TypeConfiguration.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/TypeConfiguration.java @@ -32,14 +32,15 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import com.oracle.svm.core.configure.ConfigurationParser; -import com.oracle.svm.core.configure.ReflectionConfigurationParser; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; -import com.oracle.svm.core.util.json.JsonWriter; import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; +import com.oracle.svm.core.configure.ConfigurationParser; +import com.oracle.svm.core.configure.ReflectionConfigurationParser; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.core.util.json.JsonWriter; public final class TypeConfiguration extends ConfigurationBase { @@ -93,7 +94,7 @@ protected void removeIf(Predicate predicate) { types.entrySet().removeIf(entry -> predicate.testIncludedType(entry.getKey(), entry.getValue())); } - public ConfigurationType get(ConfigurationCondition condition, String qualifiedJavaName) { + public ConfigurationType get(UnresolvedConfigurationCondition condition, String qualifiedJavaName) { return types.get(new ConditionalElement<>(condition, qualifiedJavaName)); } @@ -115,12 +116,12 @@ public void addOrMerge(ConfigurationType type) { }); } - public ConfigurationType getOrCreateType(ConfigurationCondition condition, String qualifiedForNameString) { - return types.computeIfAbsent(new ConditionalElement<>(condition, qualifiedForNameString), p -> new ConfigurationType(p.getCondition(), p.getElement())); + public ConfigurationType getOrCreateType(UnresolvedConfigurationCondition condition, String qualifiedForNameString) { + return types.computeIfAbsent(new ConditionalElement<>(condition, qualifiedForNameString), p -> new ConfigurationType(p.condition(), p.element())); } @Override - public void mergeConditional(ConfigurationCondition condition, TypeConfiguration other) { + public void mergeConditional(UnresolvedConfigurationCondition condition, TypeConfiguration other) { other.types.forEach((key, value) -> { addOrMerge(new ConfigurationType(value, condition)); }); @@ -143,7 +144,7 @@ public void printJson(JsonWriter writer) throws IOException { @Override public ConfigurationParser createParser() { - return new ReflectionConfigurationParser<>(new ParserConfigurationAdapter(this), true, false); + return new ReflectionConfigurationParser<>(ConfigurationConditionResolver.identityResolver(), new ParserConfigurationAdapter(this), true, false); } @Override diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationComputer.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationComputer.java index 85d2b3568483..dbb6d2e2a829 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationComputer.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationComputer.java @@ -32,11 +32,12 @@ import java.util.Map; import java.util.Set; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.ConfigurationBase; import com.oracle.svm.configure.config.ConfigurationSet; import com.oracle.svm.configure.filters.ComplexFilter; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFile; public class ConditionalConfigurationComputer { @@ -170,26 +171,26 @@ private ConfigurationSet deduceConditionalConfiguration(Map value : methodCallNodes.values()) { for (MethodCallNode node : value) { String className = node.methodInfo.getJavaDeclaringClassName(); - ConfigurationCondition condition = ConfigurationCondition.create(className); - - addConfigurationWithCondition(configurationSet, node.configuration, condition); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.create(className); + var resolveCondition = ConfigurationConditionResolver.identityResolver().resolveCondition(condition); + addConfigurationWithCondition(configurationSet, node.configuration, resolveCondition.get()); } } - addConfigurationWithCondition(configurationSet, rootCallNode.configuration, ConfigurationCondition.alwaysTrue()); + addConfigurationWithCondition(configurationSet, rootCallNode.configuration, UnresolvedConfigurationCondition.alwaysTrue()); return configurationSet.filter(configurationFilter); } /* Force the compiler to believe us we're referring to the same type. */ - private static > void mergeWithCondition(ConfigurationSet destConfigSet, ConfigurationSet srcConfigSet, ConfigurationCondition condition, + private static > void mergeWithCondition(ConfigurationSet destConfigSet, ConfigurationSet srcConfigSet, UnresolvedConfigurationCondition condition, ConfigurationFile configType) { T destConfig = destConfigSet.getConfiguration(configType); T srcConfig = srcConfigSet.getConfiguration(configType); destConfig.mergeConditional(condition, srcConfig); } - private static void addConfigurationWithCondition(ConfigurationSet destConfigSet, ConfigurationSet srcConfigSet, ConfigurationCondition condition) { + private static void addConfigurationWithCondition(ConfigurationSet destConfigSet, ConfigurationSet srcConfigSet, UnresolvedConfigurationCondition condition) { for (ConfigurationFile configType : ConfigurationFile.agentGeneratedFiles()) { mergeWithCondition(destConfigSet, srcConfigSet, condition, configType); } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationPredicate.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationPredicate.java index 7362854a4623..49702dd12202 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationPredicate.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/conditional/ConditionalConfigurationPredicate.java @@ -50,22 +50,22 @@ public ConditionalConfigurationPredicate(ComplexFilter filter) { @Override public boolean testIncludedType(ConditionalElement conditionalElement, ConfigurationType type) { - return !filter.includes(conditionalElement.getCondition().getTypeName()) || !filter.includes(type.getQualifiedJavaName()); + return !filter.includes(conditionalElement.condition().getTypeName()) || !filter.includes(type.getQualifiedJavaName()); } @Override public boolean testProxyInterfaceList(ConditionalElement> conditionalElement) { - return !filter.includes(conditionalElement.getCondition().getTypeName()); + return !filter.includes(conditionalElement.condition().getTypeName()); } @Override public boolean testIncludedResource(ConditionalElement condition, Pattern pattern) { - return !filter.includes(condition.getCondition().getTypeName()); + return !filter.includes(condition.condition().getTypeName()); } @Override public boolean testIncludedBundle(ConditionalElement condition, ResourceConfiguration.BundleConfiguration bundleConfiguration) { - return !filter.includes(condition.getCondition().getTypeName()); + return !filter.includes(condition.condition().getTypeName()); } @Override diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java index a65863b76e98..822757dee925 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/JniProcessor.java @@ -29,15 +29,15 @@ import java.util.List; import org.graalvm.collections.EconomicMap; -import jdk.graal.compiler.phases.common.LazyValue; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberDeclaration; -import com.oracle.svm.util.LogUtils; import com.oracle.svm.configure.config.ConfigurationMethod; import com.oracle.svm.configure.config.ConfigurationSet; import com.oracle.svm.configure.config.TypeConfiguration; +import com.oracle.svm.util.LogUtils; +import jdk.graal.compiler.phases.common.LazyValue; import jdk.vm.ci.meta.MetaUtil; class JniProcessor extends AbstractProcessor { @@ -50,7 +50,7 @@ class JniProcessor extends AbstractProcessor { @Override @SuppressWarnings("fallthrough") void processEntry(EconomicMap entry, ConfigurationSet configurationSet) { - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); boolean invalidResult = Boolean.FALSE.equals(entry.get("result")); if (invalidResult) { return; diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/ReflectionProcessor.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/ReflectionProcessor.java index 9d8f66401581..5f63ef5e89f5 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/ReflectionProcessor.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/ReflectionProcessor.java @@ -32,8 +32,7 @@ import java.util.regex.Pattern; import org.graalvm.collections.EconomicMap; -import jdk.graal.compiler.phases.common.LazyValue; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberAccessibility; import com.oracle.svm.configure.config.ConfigurationMemberInfo.ConfigurationMemberDeclaration; @@ -44,6 +43,7 @@ import com.oracle.svm.configure.config.SignatureUtil; import com.oracle.svm.configure.config.TypeConfiguration; +import jdk.graal.compiler.phases.common.LazyValue; import jdk.vm.ci.meta.MetaUtil; class ReflectionProcessor extends AbstractProcessor { @@ -57,7 +57,7 @@ class ReflectionProcessor extends AbstractProcessor { @SuppressWarnings("fallthrough") public void processEntry(EconomicMap entry, ConfigurationSet configurationSet) { boolean invalidResult = Boolean.FALSE.equals(entry.get("result")); - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); if (invalidResult) { return; } @@ -282,7 +282,7 @@ private static void addFullyQualifiedDeclaredMethod(String descriptor, TypeConfi String qualifiedClass = descriptor.substring(0, classend); String methodName = descriptor.substring(classend + 1, sigbegin); String signature = descriptor.substring(sigbegin); - configuration.getOrCreateType(ConfigurationCondition.alwaysTrue(), qualifiedClass).addMethod(methodName, signature, ConfigurationMemberDeclaration.DECLARED); + configuration.getOrCreateType(UnresolvedConfigurationCondition.alwaysTrue(), qualifiedClass).addMethod(methodName, signature, ConfigurationMemberDeclaration.DECLARED); } private void addDynamicProxy(List interfaceList, LazyValue callerClass, ProxyConfiguration proxyConfiguration) { @@ -293,7 +293,7 @@ private void addDynamicProxy(List interfaceList, LazyValue callerClas return; } } - proxyConfiguration.add(ConfigurationCondition.alwaysTrue(), interfaces); + proxyConfiguration.add(UnresolvedConfigurationCondition.alwaysTrue(), interfaces); } private void addDynamicProxyUnchecked(List checkedInterfaceList, List uncheckedInterfaceList, LazyValue callerClass, ProxyConfiguration proxyConfiguration) { @@ -310,6 +310,6 @@ private void addDynamicProxyUnchecked(List checkedInterfaceList, List unch List interfaces = new ArrayList<>(); interfaces.addAll(checkedInterfaces); interfaces.addAll(uncheckedInterfaces); - proxyConfiguration.add(ConfigurationCondition.alwaysTrue(), interfaces); + proxyConfiguration.add(UnresolvedConfigurationCondition.alwaysTrue(), interfaces); } } diff --git a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/SerializationProcessor.java b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/SerializationProcessor.java index 78278bc025f5..2ef063061a2b 100644 --- a/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/SerializationProcessor.java +++ b/substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/trace/SerializationProcessor.java @@ -30,12 +30,13 @@ import java.util.List; import org.graalvm.collections.EconomicMap; -import jdk.graal.compiler.java.LambdaUtils; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.configure.config.ConfigurationSet; import com.oracle.svm.configure.config.SerializationConfiguration; +import jdk.graal.compiler.java.LambdaUtils; + public class SerializationProcessor extends AbstractProcessor { private final AccessAdvisor advisor; @@ -47,10 +48,10 @@ public SerializationProcessor(AccessAdvisor advisor) { @SuppressWarnings("unchecked") void processEntry(EconomicMap entry, ConfigurationSet configurationSet) { boolean invalidResult = Boolean.FALSE.equals(entry.get("result")); - ConfigurationCondition condition = ConfigurationCondition.alwaysTrue(); if (invalidResult) { return; } + UnresolvedConfigurationCondition condition = UnresolvedConfigurationCondition.alwaysTrue(); String function = (String) entry.get("function"); List args = (List) entry.get("args"); SerializationConfiguration serializationConfiguration = configurationSet.getSerializationConfiguration(); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConditionalElement.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConditionalElement.java index cefaef14f10c..e54bc80cf717 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConditionalElement.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConditionalElement.java @@ -26,57 +26,23 @@ package com.oracle.svm.core.configure; import java.util.Comparator; -import java.util.Objects; import java.util.function.Function; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; -public class ConditionalElement { - private final ConfigurationCondition condition; - private final T element; - - public ConditionalElement(ConfigurationCondition condition, T element) { - this.condition = condition; - this.element = element; - } - - public ConfigurationCondition getCondition() { - return condition; - } - - public T getElement() { - return element; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ConditionalElement that = (ConditionalElement) o; - return Objects.equals(condition, that.condition) && - Objects.equals(element, that.element); - } - - @Override - public int hashCode() { - return Objects.hash(condition, element); - } +public record ConditionalElement(UnresolvedConfigurationCondition condition, T element) { public static > Comparator> comparator() { return (o1, o2) -> Comparator - .comparing((Function, T>) ConditionalElement::getElement) - .thenComparing(ConditionalElement::getCondition) + .comparing((Function, T>) ConditionalElement::element) + .thenComparing(ConditionalElement::condition) .compare(o1, o2); } public static Comparator> comparator(Comparator elementComparator) { return (o1, o2) -> Comparator - .comparing((Function, T>) ConditionalElement::getElement, elementComparator) - .thenComparing(ConditionalElement::getCondition) + .comparing((Function, T>) ConditionalElement::element, elementComparator) + .thenComparing(ConditionalElement::condition) .compare(o1, o2); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/LocalizationFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationConditionResolver.java similarity index 52% rename from substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/LocalizationFeature.java rename to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationConditionResolver.java index 7b4190e1a9b8..435eeab05b1c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/LocalizationFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ConfigurationConditionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,29 +22,29 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.svm.core.jdk.localization; +package com.oracle.svm.core.configure; -import org.graalvm.nativeimage.ImageSingletons; -import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; -import com.oracle.svm.core.configure.ResourcesRegistry; -import com.oracle.svm.core.feature.InternalFeature; -import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature; +import com.oracle.svm.core.TypeResult; -/** - * This class is just a delegate. The real LocalizationFeature is now in - * com.oracle.svm.hosted.jdk.localization. It was created in order to ensure backwards compatibility - * for code depending on the location of the feature. - */ -@AutomaticallyRegisteredFeature -public class LocalizationFeature implements InternalFeature { +public interface ConfigurationConditionResolver { + + static ConfigurationConditionResolver identityResolver() { + return new ConfigurationConditionResolver<>() { + @Override + public TypeResult resolveCondition(UnresolvedConfigurationCondition unresolvedCondition) { + return TypeResult.forType(unresolvedCondition.getTypeName(), unresolvedCondition); + } - /** - * @deprecated Use {@link ResourcesRegistry#addResourceBundles(ConfigurationCondition, String)} - * instead. - */ - @Deprecated - public void prepareBundle(String baseName) { - ImageSingletons.lookup(ResourcesRegistry.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), baseName); + @Override + public UnresolvedConfigurationCondition alwaysTrue() { + return UnresolvedConfigurationCondition.create("java.lang.Object"); + } + }; } + + TypeResult resolveCondition(UnresolvedConfigurationCondition unresolvedCondition); + + T alwaysTrue(); } 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 d5b5a1642c71..beefc34476a4 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 @@ -40,15 +40,16 @@ import java.util.Set; import org.graalvm.collections.EconomicMap; -import org.graalvm.nativeimage.impl.ConfigurationCondition; -import jdk.graal.compiler.util.json.JSONParser; -import jdk.graal.compiler.util.json.JSONParserException; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.jdk.JavaNetSubstitutions; import com.oracle.svm.core.util.VMError; import com.oracle.svm.util.LogUtils; +import jdk.graal.compiler.util.json.JSONParser; +import jdk.graal.compiler.util.json.JSONParserException; + public abstract class ConfigurationParser { public static InputStream openStream(URI uri) throws IOException { URL url = uri.toURL(); @@ -61,6 +62,8 @@ public static InputStream openStream(URI uri) throws IOException { public static final String CONDITIONAL_KEY = "condition"; public static final String TYPE_REACHABLE_KEY = "typeReachable"; + + public static final String TYPE_REACHED_KEY = "typeReached"; private final Map> seenUnknownAttributesByType = new HashMap<>(); private final boolean strictSchema; @@ -180,18 +183,19 @@ protected static long asLong(Object value, String propertyName) { throw new JSONParserException("Invalid long value '" + value + "' for element '" + propertyName + "'"); } - protected ConfigurationCondition parseCondition(EconomicMap data) { + protected UnresolvedConfigurationCondition parseCondition(EconomicMap data) { Object conditionData = data.get(CONDITIONAL_KEY); if (conditionData != null) { EconomicMap conditionObject = asMap(conditionData, "Attribute 'condition' must be an object"); + Object conditionType = conditionObject.get(TYPE_REACHABLE_KEY); if (conditionType instanceof String) { - return ConfigurationCondition.create((String) conditionType); + return UnresolvedConfigurationCondition.create((String) conditionType); } else { warnOrFailOnSchemaError("'" + TYPE_REACHABLE_KEY + "' should be of type string"); } } - return ConfigurationCondition.alwaysTrue(); + return UnresolvedConfigurationCondition.alwaysTrue(); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ProxyConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ProxyConfigurationParser.java index ba8b99f0971b..48a268311fac 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ProxyConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ProxyConfigurationParser.java @@ -27,24 +27,31 @@ import java.net.URI; import java.util.Collections; import java.util.List; -import java.util.function.Consumer; +import java.util.function.BiConsumer; import java.util.stream.Collectors; import org.graalvm.collections.EconomicMap; -import org.graalvm.nativeimage.impl.ConfigurationCondition; -import jdk.graal.compiler.util.json.JSONParserException; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; +import com.oracle.svm.core.TypeResult; import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; +import jdk.graal.compiler.util.json.JSONParserException; + /** * Parses JSON describing lists of interfaces and register them in the {@link DynamicProxyRegistry}. */ -public final class ProxyConfigurationParser extends ConfigurationParser { - private final Consumer>> interfaceListConsumer; +public final class ProxyConfigurationParser extends ConfigurationParser { - public ProxyConfigurationParser(Consumer>> interfaceListConsumer, boolean strictConfiguration) { + private final ConfigurationConditionResolver conditionResolver; + + private final BiConsumer> proxyConfigConsumer; + + public ProxyConfigurationParser(ConfigurationConditionResolver conditionResolver, boolean strictConfiguration, + BiConsumer> proxyConfigConsumer) { super(strictConfiguration); - this.interfaceListConsumer = interfaceListConsumer; + this.proxyConfigConsumer = proxyConfigConsumer; + this.conditionResolver = conditionResolver; } @Override @@ -58,7 +65,7 @@ private void parseTopLevelArray(List proxyConfiguration) { for (Object proxyConfigurationObject : proxyConfiguration) { if (proxyConfigurationObject instanceof List) { foundInterfaceLists = true; - parseInterfaceList(ConfigurationCondition.alwaysTrue(), asList(proxyConfigurationObject, "")); + parseInterfaceList(conditionResolver.alwaysTrue(), asList(proxyConfigurationObject, "")); } else if (proxyConfigurationObject instanceof EconomicMap) { foundProxyConfigurationObjects = true; parseWithConditionalConfig(asMap(proxyConfigurationObject, "")); @@ -71,11 +78,11 @@ private void parseTopLevelArray(List proxyConfiguration) { } } - private void parseInterfaceList(ConfigurationCondition condition, List data) { + private void parseInterfaceList(C condition, List data) { List interfaces = data.stream().map(ConfigurationParser::asString).collect(Collectors.toList()); try { - interfaceListConsumer.accept(new ConditionalElement<>(condition, interfaces)); + proxyConfigConsumer.accept(condition, interfaces); } catch (Exception e) { throw new JSONParserException(e.toString()); } @@ -83,7 +90,10 @@ private void parseInterfaceList(ConfigurationCondition condition, List data) private void parseWithConditionalConfig(EconomicMap proxyConfigObject) { checkAttributes(proxyConfigObject, "proxy descriptor object", Collections.singleton("interfaces"), Collections.singletonList(CONDITIONAL_KEY)); - ConfigurationCondition condition = parseCondition(proxyConfigObject); - parseInterfaceList(condition, asList(proxyConfigObject.get("interfaces"), "The interfaces property must be an array of fully qualified interface names")); + UnresolvedConfigurationCondition condition = parseCondition(proxyConfigObject); + TypeResult resolvedCondition = conditionResolver.resolveCondition(condition); + if (resolvedCondition.isPresent()) { + parseInterfaceList(resolvedCondition.get(), asList(proxyConfigObject.get("interfaces"), "The interfaces property must be an array of fully qualified interface names")); + } } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParser.java index c93041c6b39d..2632343f0a5a 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParser.java @@ -33,20 +33,21 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.MapCursor; -import org.graalvm.nativeimage.impl.ConfigurationCondition; -import jdk.graal.compiler.util.json.JSONParserException; import com.oracle.svm.core.TypeResult; import com.oracle.svm.util.LogUtils; +import jdk.graal.compiler.util.json.JSONParserException; + /** * Parses JSON describing classes, methods and fields and delegates their registration to a * {@link ReflectionConfigurationParserDelegate}. */ -public final class ReflectionConfigurationParser extends ConfigurationParser { +public final class ReflectionConfigurationParser extends ConfigurationParser { private static final String CONSTRUCTOR_NAME = ""; - private final ReflectionConfigurationParserDelegate delegate; + private final ConfigurationConditionResolver conditionResolver; + private final ReflectionConfigurationParserDelegate delegate; private static final List OPTIONAL_REFLECT_CONFIG_OBJECT_ATTRS = Arrays.asList("allDeclaredConstructors", "allPublicConstructors", "allDeclaredMethods", "allPublicMethods", "allDeclaredFields", "allPublicFields", "allDeclaredClasses", "allRecordComponents", "allPermittedSubclasses", "allNestMembers", "allSigners", @@ -54,12 +55,10 @@ public final class ReflectionConfigurationParser extends ConfigurationParser "queryAllDeclaredConstructors", "queryAllPublicConstructors", "queryAllDeclaredMethods", "queryAllPublicMethods", "unsafeAllocated"); private final boolean printMissingElements; - public ReflectionConfigurationParser(ReflectionConfigurationParserDelegate delegate) { - this(delegate, true, false); - } - - public ReflectionConfigurationParser(ReflectionConfigurationParserDelegate delegate, boolean strictConfiguration, boolean printMissingElements) { + public ReflectionConfigurationParser(ConfigurationConditionResolver conditionResolver, ReflectionConfigurationParserDelegate delegate, boolean strictConfiguration, + boolean printMissingElements) { super(strictConfiguration); + this.conditionResolver = conditionResolver; this.printMissingElements = printMissingElements; this.delegate = delegate; } @@ -81,23 +80,23 @@ private void parseClass(EconomicMap data) { Object classObject = data.get("name"); String className = asString(classObject, "name"); - TypeResult conditionResult = delegate.resolveCondition(parseCondition(data).getTypeName()); + TypeResult conditionResult = conditionResolver.resolveCondition(parseCondition(data)); if (!conditionResult.isPresent()) { return; } - ConfigurationCondition condition = conditionResult.get(); /* * 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, className, true); if (!result.isPresent()) { handleMissingElement("Could not resolve class " + className + " for reflection configuration.", result.getException()); return; } T clazz = result.get(); - delegate.registerType(clazz); + delegate.registerType(conditionResult.get(), clazz); MapCursor cursor = data.getEntries(); while (cursor.advance()) { @@ -107,97 +106,97 @@ private void parseClass(EconomicMap data) { switch (name) { case "allDeclaredConstructors": if (asBoolean(value, "allDeclaredConstructors")) { - delegate.registerDeclaredConstructors(false, clazz); + delegate.registerDeclaredConstructors(condition, false, clazz); } break; case "allPublicConstructors": if (asBoolean(value, "allPublicConstructors")) { - delegate.registerPublicConstructors(false, clazz); + delegate.registerPublicConstructors(condition, false, clazz); } break; case "allDeclaredMethods": if (asBoolean(value, "allDeclaredMethods")) { - delegate.registerDeclaredMethods(false, clazz); + delegate.registerDeclaredMethods(condition, false, clazz); } break; case "allPublicMethods": if (asBoolean(value, "allPublicMethods")) { - delegate.registerPublicMethods(false, clazz); + delegate.registerPublicMethods(condition, false, clazz); } break; case "allDeclaredFields": if (asBoolean(value, "allDeclaredFields")) { - delegate.registerDeclaredFields(clazz); + delegate.registerDeclaredFields(condition, clazz); } break; case "allPublicFields": if (asBoolean(value, "allPublicFields")) { - delegate.registerPublicFields(clazz); + delegate.registerPublicFields(condition, clazz); } break; case "allDeclaredClasses": if (asBoolean(value, "allDeclaredClasses")) { - delegate.registerDeclaredClasses(clazz); + delegate.registerDeclaredClasses(condition, clazz); } break; case "allRecordComponents": if (asBoolean(value, "allRecordComponents")) { - delegate.registerRecordComponents(clazz); + delegate.registerRecordComponents(condition, clazz); } break; case "allPermittedSubclasses": if (asBoolean(value, "allPermittedSubclasses")) { - delegate.registerPermittedSubclasses(clazz); + delegate.registerPermittedSubclasses(condition, clazz); } break; case "allNestMembers": if (asBoolean(value, "allNestMembers")) { - delegate.registerNestMembers(clazz); + delegate.registerNestMembers(condition, clazz); } break; case "allSigners": if (asBoolean(value, "allSigners")) { - delegate.registerSigners(clazz); + delegate.registerSigners(condition, clazz); } break; case "allPublicClasses": if (asBoolean(value, "allPublicClasses")) { - delegate.registerPublicClasses(clazz); + delegate.registerPublicClasses(condition, clazz); } break; case "queryAllDeclaredConstructors": if (asBoolean(value, "queryAllDeclaredConstructors")) { - delegate.registerDeclaredConstructors(true, clazz); + delegate.registerDeclaredConstructors(condition, true, clazz); } break; case "queryAllPublicConstructors": if (asBoolean(value, "queryAllPublicConstructors")) { - delegate.registerPublicConstructors(true, clazz); + delegate.registerPublicConstructors(condition, true, clazz); } break; case "queryAllDeclaredMethods": if (asBoolean(value, "queryAllDeclaredMethods")) { - delegate.registerDeclaredMethods(true, clazz); + delegate.registerDeclaredMethods(condition, true, clazz); } break; case "queryAllPublicMethods": if (asBoolean(value, "queryAllPublicMethods")) { - delegate.registerPublicMethods(true, clazz); + delegate.registerPublicMethods(condition, true, clazz); } break; case "unsafeAllocated": if (asBoolean(value, "unsafeAllocated")) { - delegate.registerUnsafeAllocated(clazz); + delegate.registerUnsafeAllocated(condition, clazz); } break; case "methods": - parseMethods(false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz); + parseMethods(condition, false, asList(value, "Attribute 'methods' must be an array of method descriptors"), clazz); break; case "queriedMethods": - parseMethods(true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz); + parseMethods(condition, true, asList(value, "Attribute 'queriedMethods' must be an array of method descriptors"), clazz); break; case "fields": - parseFields(asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz); + parseFields(condition, asList(value, "Attribute 'fields' must be an array of field descriptors"), clazz); break; } } catch (LinkageError e) { @@ -206,19 +205,19 @@ private void parseClass(EconomicMap data) { } } - private void parseFields(List fields, T clazz) { + private void parseFields(C condition, List fields, T clazz) { for (Object field : fields) { - parseField(asMap(field, "Elements of 'fields' array must be field descriptor objects"), clazz); + parseField(condition, asMap(field, "Elements of 'fields' array must be field descriptor objects"), clazz); } } - private void parseField(EconomicMap data, T clazz) { + private void parseField(C condition, EconomicMap data, T clazz) { checkAttributes(data, "reflection field descriptor object", Collections.singleton("name"), Arrays.asList("allowWrite", "allowUnsafeAccess")); String fieldName = asString(data.get("name"), "name"); boolean allowWrite = data.containsKey("allowWrite") && asBoolean(data.get("allowWrite"), "allowWrite"); try { - delegate.registerField(clazz, fieldName, allowWrite); + delegate.registerField(condition, clazz, fieldName, allowWrite); } catch (NoSuchFieldException e) { handleMissingElement("Field " + formatField(clazz, fieldName) + " not found."); } catch (LinkageError e) { @@ -226,13 +225,13 @@ private void parseField(EconomicMap data, T clazz) { } } - private void parseMethods(boolean queriedOnly, List methods, T clazz) { + private void parseMethods(C condition, boolean queriedOnly, List methods, T clazz) { for (Object method : methods) { - parseMethod(queriedOnly, asMap(method, "Elements of 'methods' array must be method descriptor objects"), clazz); + parseMethod(condition, queriedOnly, asMap(method, "Elements of 'methods' array must be method descriptor objects"), clazz); } } - private void parseMethod(boolean queriedOnly, EconomicMap data, T clazz) { + private void parseMethod(C condition, boolean queriedOnly, EconomicMap data, T clazz) { checkAttributes(data, "reflection method descriptor object", Collections.singleton("name"), Collections.singleton("parameterTypes")); String methodName = asString(data.get("name"), "name"); List methodParameterTypes = null; @@ -248,9 +247,9 @@ private void parseMethod(boolean queriedOnly, EconomicMap data, if (methodParameterTypes != null) { try { if (isConstructor) { - delegate.registerConstructor(queriedOnly, clazz, methodParameterTypes); + delegate.registerConstructor(condition, queriedOnly, clazz, methodParameterTypes); } else { - delegate.registerMethod(queriedOnly, clazz, methodName, methodParameterTypes); + delegate.registerMethod(condition, queriedOnly, clazz, methodName, methodParameterTypes); } } catch (NoSuchMethodException e) { handleMissingElement("Method " + formatMethod(clazz, methodName, methodParameterTypes) + " not found."); @@ -261,9 +260,9 @@ private void parseMethod(boolean queriedOnly, EconomicMap data, try { boolean found; if (isConstructor) { - found = delegate.registerAllConstructors(queriedOnly, clazz); + found = delegate.registerAllConstructors(condition, queriedOnly, clazz); } else { - found = delegate.registerAllMethodsWithName(queriedOnly, clazz, methodName); + found = delegate.registerAllMethodsWithName(condition, queriedOnly, clazz, methodName); } if (!found) { throw new JSONParserException("Method " + formatMethod(clazz, methodName) + " not found"); @@ -278,7 +277,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(ConfigurationCondition.alwaysTrue(), typeName, true); + TypeResult typeResult = delegate.resolveType(conditionResolver.alwaysTrue(), typeName, true); 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.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java index 7cbce8f012f5..b4b29c58c525 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java @@ -26,53 +26,49 @@ import java.util.List; -import org.graalvm.nativeimage.impl.ConfigurationCondition; - import com.oracle.svm.core.TypeResult; -public interface ReflectionConfigurationParserDelegate { - - TypeResult resolveCondition(String typeName); +public interface ReflectionConfigurationParserDelegate { - TypeResult resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives); + TypeResult resolveType(C condition, String typeName, boolean allowPrimitives); - void registerType(T type); + void registerType(C condition, T type); - void registerPublicClasses(T type); + void registerPublicClasses(C condition, T type); - void registerDeclaredClasses(T type); + void registerDeclaredClasses(C condition, T type); - void registerRecordComponents(T type); + void registerRecordComponents(C condition, T type); - void registerPermittedSubclasses(T type); + void registerPermittedSubclasses(C condition, T type); - void registerNestMembers(T type); + void registerNestMembers(C condition, T type); - void registerSigners(T type); + void registerSigners(C condition, T type); - void registerPublicFields(T type); + void registerPublicFields(C condition, T type); - void registerDeclaredFields(T type); + void registerDeclaredFields(C condition, T type); - void registerPublicMethods(boolean queriedOnly, T type); + void registerPublicMethods(C condition, boolean queriedOnly, T type); - void registerDeclaredMethods(boolean queriedOnly, T type); + void registerDeclaredMethods(C condition, boolean queriedOnly, T type); - void registerPublicConstructors(boolean queriedOnly, T type); + void registerPublicConstructors(C condition, boolean queriedOnly, T type); - void registerDeclaredConstructors(boolean queriedOnly, T type); + void registerDeclaredConstructors(C condition, boolean queriedOnly, T type); - void registerField(T type, String fieldName, boolean allowWrite) throws NoSuchFieldException; + void registerField(C condition, T type, String fieldName, boolean allowWrite) throws NoSuchFieldException; - boolean registerAllMethodsWithName(boolean queriedOnly, T type, String methodName); + boolean registerAllMethodsWithName(C condition, boolean queriedOnly, T type, String methodName); - void registerMethod(boolean queriedOnly, T type, String methodName, List methodParameterTypes) throws NoSuchMethodException; + void registerMethod(C condition, boolean queriedOnly, T type, String methodName, List methodParameterTypes) throws NoSuchMethodException; - void registerConstructor(boolean queriedOnly, T type, List methodParameterTypes) throws NoSuchMethodException; + void registerConstructor(C condition, boolean queriedOnly, T type, List methodParameterTypes) throws NoSuchMethodException; - boolean registerAllConstructors(boolean queriedOnly, T type); + boolean registerAllConstructors(C condition, boolean queriedOnly, T type); - void registerUnsafeAllocated(T clazz); + void registerUnsafeAllocated(C condition, T clazz); String getTypeName(T type); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourceConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourceConfigurationParser.java index b3e820e38666..e2d037314212 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourceConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourceConfigurationParser.java @@ -34,17 +34,21 @@ import org.graalvm.collections.EconomicMap; import org.graalvm.collections.MapCursor; -import org.graalvm.nativeimage.impl.ConfigurationCondition; -import jdk.graal.compiler.util.json.JSONParserException; +import com.oracle.svm.core.TypeResult; import com.oracle.svm.core.jdk.localization.LocalizationSupport; -public class ResourceConfigurationParser extends ConfigurationParser { - private final ResourcesRegistry registry; +import jdk.graal.compiler.util.json.JSONParserException; + +public class ResourceConfigurationParser extends ConfigurationParser { + private final ResourcesRegistry registry; - public ResourceConfigurationParser(ResourcesRegistry registry, boolean strictConfiguration) { + private final ConfigurationConditionResolver conditionResolver; + + public ResourceConfigurationParser(ConfigurationConditionResolver conditionResolver, ResourcesRegistry registry, boolean strictConfiguration) { super(strictConfiguration); this.registry = registry; + this.conditionResolver = conditionResolver; } @Override @@ -101,7 +105,10 @@ private void parseBundle(Object bundle) { EconomicMap resource = asMap(bundle, "Elements of 'bundles' list must be a bundle descriptor object"); checkAttributes(resource, "bundle descriptor object", Collections.singletonList("name"), Arrays.asList("locales", "classNames", "condition")); String basename = asString(resource.get("name")); - ConfigurationCondition condition = parseCondition(resource); + TypeResult resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(resource)); + if (!resolvedConfigurationCondition.isPresent()) { + return; + } Object locales = resource.get("locales"); if (locales != null) { List asList = asList(locales, "Attribute 'locales' must be a list of locales") @@ -109,7 +116,7 @@ private void parseBundle(Object bundle) { .map(ResourceConfigurationParser::parseLocale) .collect(Collectors.toList()); if (!asList.isEmpty()) { - registry.addResourceBundles(condition, basename, asList); + registry.addResourceBundles(resolvedConfigurationCondition.get(), basename, asList); } } @@ -118,12 +125,12 @@ private void parseBundle(Object bundle) { List asList = asList(classNames, "Attribute 'classNames' must be a list of classes"); for (Object o : asList) { String className = asString(o); - registry.addClassBasedResourceBundle(condition, basename, className); + registry.addClassBasedResourceBundle(resolvedConfigurationCondition.get(), basename, className); } } if (locales == null && classNames == null) { /* If nothing more precise is specified, register in every included locale */ - registry.addResourceBundles(condition, basename); + registry.addResourceBundles(resolvedConfigurationCondition.get(), basename); } } @@ -136,12 +143,15 @@ private static Locale parseLocale(Object input) { return locale; } - private void parseStringEntry(Object data, String valueKey, BiConsumer resourceRegistry, String expectedType, String parentType) { + private void parseStringEntry(Object data, String valueKey, BiConsumer resourceRegistry, String expectedType, String parentType) { EconomicMap resource = asMap(data, "Elements of " + parentType + " must be a " + expectedType); checkAttributes(resource, "resource and resource bundle descriptor object", Collections.singletonList(valueKey), Collections.singletonList(CONDITIONAL_KEY)); - ConfigurationCondition condition = parseCondition(resource); + TypeResult resolvedConfigurationCondition = conditionResolver.resolveCondition(parseCondition(resource)); + if (!resolvedConfigurationCondition.isPresent()) { + return; + } Object valueObject = resource.get(valueKey); String value = asString(valueObject, valueKey); - resourceRegistry.accept(condition, value); + resourceRegistry.accept(resolvedConfigurationCondition.get(), value); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourcesRegistry.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourcesRegistry.java index df941c65f45c..89ce92951e1b 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourcesRegistry.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ResourcesRegistry.java @@ -27,41 +27,18 @@ import java.util.Collection; import java.util.Locale; +import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeResourceSupport; -public interface ResourcesRegistry extends RuntimeResourceSupport { +public interface ResourcesRegistry extends RuntimeResourceSupport { - /** - * @deprecated Use {@link RuntimeResourceSupport#addResources(ConfigurationCondition, String)} - * instead. - */ - @Deprecated - default void addResources(String pattern) { - addResources(ConfigurationCondition.alwaysTrue(), pattern); - } - - /** - * @deprecated Use - * {@link RuntimeResourceSupport#ignoreResources(ConfigurationCondition, String)} - * instead. - */ - @Deprecated - default void ignoreResources(String pattern) { - ignoreResources(ConfigurationCondition.alwaysTrue(), pattern); - } - - /** - * @deprecated Use - * {@link RuntimeResourceSupport#addResourceBundles(ConfigurationCondition, String)} - * instead. - */ - @Deprecated - default void addResourceBundles(String name) { - addResourceBundles(ConfigurationCondition.alwaysTrue(), name); + @SuppressWarnings("unchecked") + static ResourcesRegistry singleton() { + return ImageSingletons.lookup(ResourcesRegistry.class); } - void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className); + void addClassBasedResourceBundle(C condition, String basename, String className); /** * Although the interface-methods below are already defined in the super-interface @@ -69,14 +46,14 @@ default void addResourceBundles(String name) { * reflectively. */ @Override - void addResources(ConfigurationCondition condition, String pattern); + void addResources(C condition, String pattern); @Override - void ignoreResources(ConfigurationCondition condition, String pattern); + void ignoreResources(C condition, String pattern); @Override - void addResourceBundles(ConfigurationCondition condition, String name); + void addResourceBundles(C condition, String name); @Override - void addResourceBundles(ConfigurationCondition condition, String basename, Collection locales); + void addResourceBundles(C condition, String basename, Collection locales); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/SerializationConfigurationParser.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/SerializationConfigurationParser.java index b2928ed538c1..5a89eddef9e8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/SerializationConfigurationParser.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/SerializationConfigurationParser.java @@ -31,25 +31,28 @@ import java.util.List; import org.graalvm.collections.EconomicMap; -import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeSerializationSupport; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; + import jdk.graal.compiler.util.json.JSONParserException; -public class SerializationConfigurationParser extends ConfigurationParser { +public class SerializationConfigurationParser extends ConfigurationParser { public static final String NAME_KEY = "name"; public static final String CUSTOM_TARGET_CONSTRUCTOR_CLASS_KEY = "customTargetConstructorClass"; private static final String SERIALIZATION_TYPES_KEY = "types"; private static final String LAMBDA_CAPTURING_SERIALIZATION_TYPES_KEY = "lambdaCapturingTypes"; private static final String PROXY_SERIALIZATION_TYPES_KEY = "proxies"; - private final RuntimeSerializationSupport serializationSupport; - private final ProxyConfigurationParser proxyConfigurationParser; - public SerializationConfigurationParser(RuntimeSerializationSupport serializationSupport, boolean strictConfiguration) { + private final ConfigurationConditionResolver conditionResolver; + private final RuntimeSerializationSupport serializationSupport; + private final ProxyConfigurationParser proxyConfigurationParser; + + public SerializationConfigurationParser(ConfigurationConditionResolver conditionResolver, RuntimeSerializationSupport serializationSupport, boolean strictConfiguration) { super(strictConfiguration); this.serializationSupport = serializationSupport; - this.proxyConfigurationParser = new ProxyConfigurationParser( - (conditionalElement) -> serializationSupport.registerProxyClass(conditionalElement.getCondition(), conditionalElement.getElement()), strictConfiguration); + this.proxyConfigurationParser = new ProxyConfigurationParser<>(conditionResolver, strictConfiguration, serializationSupport::registerProxyClass); + this.conditionResolver = conditionResolver; } @Override @@ -96,15 +99,19 @@ private void parseSerializationDescriptorObject(EconomicMap data checkAttributes(data, "serialization descriptor object", Collections.singleton(NAME_KEY), Arrays.asList(CUSTOM_TARGET_CONSTRUCTOR_CLASS_KEY, CONDITIONAL_KEY)); } - ConfigurationCondition unresolvedCondition = parseCondition(data); + UnresolvedConfigurationCondition unresolvedCondition = parseCondition(data); + var condition = conditionResolver.resolveCondition(unresolvedCondition); + if (!condition.isPresent()) { + return; + } String targetSerializationClass = asString(data.get(NAME_KEY)); if (lambdaCapturingType) { - serializationSupport.registerLambdaCapturingClass(unresolvedCondition, targetSerializationClass); + serializationSupport.registerLambdaCapturingClass(condition.get(), targetSerializationClass); } else { Object optionalCustomCtorValue = data.get(CUSTOM_TARGET_CONSTRUCTOR_CLASS_KEY); String customTargetConstructorClass = optionalCustomCtorValue != null ? asString(optionalCustomCtorValue) : null; - serializationSupport.registerWithTargetConstructorClass(unresolvedCondition, targetSerializationClass, customTargetConstructorClass); + serializationSupport.registerWithTargetConstructorClass(condition.get(), targetSerializationClass, customTargetConstructorClass); } } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java index 9cbd634ff899..59aa86fb65a7 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JavaNetHttpFeature.java @@ -94,7 +94,7 @@ public void afterRegistration(AfterRegistrationAccess access) { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerReachabilityHandler(a -> { - ImageSingletons.lookup(ResourcesRegistry.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "sun.net.httpserver.simpleserver.resources.simpleserver"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "sun.net.httpserver.simpleserver.resources.simpleserver"); }, access.findClassByName("sun.net.httpserver.simpleserver.SimpleFileServerImpl")); } } diff --git a/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignFunctionsFeature.java b/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignFunctionsFeature.java index 24cced11e590..4c2fc4891f15 100644 --- a/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignFunctionsFeature.java +++ b/substratevm/src/com.oracle.svm.hosted.foreign/src/com/oracle/svm/hosted/foreign/ForeignFunctionsFeature.java @@ -102,7 +102,7 @@ private class RuntimeForeignAccessSupportImpl extends ConditionalConfigurationRe @Override public void registerForDowncall(ConfigurationCondition condition, FunctionDescriptor desc, Linker.Option... options) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> registeredDowncalls.add(Pair.create(desc, options))); + registerConditionalConfiguration(condition, (cnd) -> registeredDowncalls.add(Pair.create(desc, options))); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java index 433b0680c4b1..82a18a81a6a6 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ClassLoaderSupportImpl.java @@ -220,7 +220,7 @@ private static void scanJar(Path jarPath, ResourceCollector collector, boolean i } private static void includeResource(ResourceCollector collector, Module module, String name, ConfigurationCondition condition) { - if (ConfigurationCondition.isAlwaysTrue(condition)) { + if (condition.isAlwaysTrue()) { collector.addResource(module, name); } else { collector.addResourceConditionally(module, name, condition); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConditionalConfigurationRegistry.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConditionalConfigurationRegistry.java index 8af9e717078f..371cba683816 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConditionalConfigurationRegistry.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConditionalConfigurationRegistry.java @@ -29,31 +29,31 @@ import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.impl.ConfigurationCondition; -import com.oracle.svm.core.TypeResult; - public abstract class ConditionalConfigurationRegistry { - private final Map> pendingReachabilityHandlers = new ConcurrentHashMap<>(); + private final Map, Collection> pendingReachabilityHandlers = new ConcurrentHashMap<>(); - protected void registerConditionalConfiguration(ConfigurationCondition condition, Runnable runnable) { + protected void registerConditionalConfiguration(ConfigurationCondition condition, Consumer consumer) { Objects.requireNonNull(condition, "Cannot use null value as condition for conditional configuration. Please ensure that you register a non-null condition."); - Objects.requireNonNull(runnable, "Cannot use null value as runnable for conditional configuration. Please ensure that you register a non-null runnable."); + Objects.requireNonNull(consumer, "Cannot use null value as runnable for conditional configuration. Please ensure that you register a non-null runnable."); if (ConfigurationCondition.alwaysTrue().equals(condition)) { /* analysis optimization to include new types as early as possible */ - runnable.run(); + consumer.accept(condition); } else { - Collection handlers = pendingReachabilityHandlers.computeIfAbsent(condition.getTypeName(), key -> new ConcurrentLinkedQueue<>()); - handlers.add(runnable); + Collection handlers = pendingReachabilityHandlers.computeIfAbsent(condition.getType(), key -> new ConcurrentLinkedQueue<>()); + ConfigurationCondition runtimeCondition = ConfigurationCondition.alwaysTrue(); + handlers.add(() -> consumer.accept(runtimeCondition)); } + } public void flushConditionalConfiguration(Feature.BeforeAnalysisAccess b) { - for (Map.Entry> reachabilityEntry : pendingReachabilityHandlers.entrySet()) { - TypeResult> typeResult = ((FeatureImpl.BeforeAnalysisAccessImpl) b).getImageClassLoader().findClass(reachabilityEntry.getKey()); - b.registerReachabilityHandler(access -> reachabilityEntry.getValue().forEach(Runnable::run), typeResult.get()); + for (Map.Entry, Collection> reachabilityEntry : pendingReachabilityHandlers.entrySet()) { + b.registerReachabilityHandler(access -> reachabilityEntry.getValue().forEach(Runnable::run), reachabilityEntry.getKey()); } pendingReachabilityHandlers.clear(); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConfigurationTypeResolver.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConfigurationTypeResolver.java index 0f8957097f86..1d01f8ee8717 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConfigurationTypeResolver.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ConfigurationTypeResolver.java @@ -38,10 +38,6 @@ public ConfigurationTypeResolver(String configurationType, ImageClassLoader clas this.classLoader = classLoader; } - public Class resolveConditionType(String typeName) { - return resolveType(typeName, false); - } - public Class resolveType(String typeName) { return resolveType(typeName, true); } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java index d3411c5847d2..fc8be2b8dbc4 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ResourcesFeature.java @@ -72,6 +72,7 @@ import com.oracle.svm.core.MissingRegistrationUtils; import com.oracle.svm.core.ParsingReason; import com.oracle.svm.core.SubstrateUtil; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.ResourceConfigurationParser; @@ -87,8 +88,10 @@ import com.oracle.svm.core.option.LocatableMultiOptionValue; import com.oracle.svm.core.util.UserError; import com.oracle.svm.core.util.VMError; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.config.ConfigurationParserUtils; import com.oracle.svm.hosted.jdk.localization.LocalizationFeature; +import com.oracle.svm.hosted.reflect.NativeImageConditionResolver; import com.oracle.svm.util.LogUtils; import com.oracle.svm.util.ModuleSupport; import com.oracle.svm.util.ReflectionUtil; @@ -159,20 +162,14 @@ private record CompiledConditionalPattern(ConfigurationCondition condition, Reso private int loadedConfigurations; private ImageClassLoader imageClassLoader; - private class ResourcesRegistryImpl extends ConditionalConfigurationRegistry implements ResourcesRegistry { - private final ConfigurationTypeResolver configurationTypeResolver; + private class ResourcesRegistryImpl extends ConditionalConfigurationRegistry implements ResourcesRegistry { private final Set alreadyAddedResources = new HashSet<>(); - ResourcesRegistryImpl(ConfigurationTypeResolver configurationTypeResolver) { - this.configurationTypeResolver = configurationTypeResolver; + ResourcesRegistryImpl() { } @Override public void addResources(ConfigurationCondition condition, String pattern) { - if (configurationTypeResolver.resolveConditionType(condition.getTypeName()) == null) { - return; - } - try { resourcePatternWorkSet.add(new ConditionalPattern(condition, pattern)); } catch (UnsupportedOperationException e) { @@ -201,10 +198,7 @@ public void injectResource(Module module, String resourcePath, byte[] resourceCo @Override public void ignoreResources(ConfigurationCondition condition, String pattern) { - if (configurationTypeResolver.resolveConditionType(condition.getTypeName()) == null) { - return; - } - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { UserError.guarantee(!sealed, "Resources ignored too late: %s", pattern); excludedResourcePatterns.add(pattern); @@ -213,26 +207,17 @@ public void ignoreResources(ConfigurationCondition condition, String pattern) { @Override public void addResourceBundles(ConfigurationCondition condition, String name) { - if (configurationTypeResolver.resolveConditionType(condition.getTypeName()) == null) { - return; - } - registerConditionalConfiguration(condition, () -> ImageSingletons.lookup(LocalizationFeature.class).prepareBundle(name)); + registerConditionalConfiguration(condition, (cnd) -> ImageSingletons.lookup(LocalizationFeature.class).prepareBundle(name)); } @Override public void addClassBasedResourceBundle(ConfigurationCondition condition, String basename, String className) { - if (configurationTypeResolver.resolveConditionType(condition.getTypeName()) == null) { - return; - } - registerConditionalConfiguration(condition, () -> ImageSingletons.lookup(LocalizationFeature.class).prepareClassResourceBundle(basename, className)); + registerConditionalConfiguration(condition, (cnd) -> ImageSingletons.lookup(LocalizationFeature.class).prepareClassResourceBundle(basename, className)); } @Override public void addResourceBundles(ConfigurationCondition condition, String basename, Collection locales) { - if (configurationTypeResolver.resolveConditionType(condition.getTypeName()) == null) { - return; - } - registerConditionalConfiguration(condition, () -> ImageSingletons.lookup(LocalizationFeature.class).prepareBundle(basename, locales)); + registerConditionalConfiguration(condition, (cnd) -> ImageSingletons.lookup(LocalizationFeature.class).prepareBundle(basename, locales)); } /* @@ -422,7 +407,7 @@ private String getDirectoryContent(String path, boolean fromJar) throws IOExcept public void afterRegistration(AfterRegistrationAccess a) { FeatureImpl.AfterRegistrationAccessImpl access = (FeatureImpl.AfterRegistrationAccessImpl) a; imageClassLoader = access.getImageClassLoader(); - ResourcesRegistryImpl resourcesRegistry = new ResourcesRegistryImpl(new ConfigurationTypeResolver("resource configuration", imageClassLoader)); + ResourcesRegistryImpl resourcesRegistry = new ResourcesRegistryImpl(); ImageSingletons.add(ResourcesRegistry.class, resourcesRegistry); ImageSingletons.add(RuntimeResourceSupport.class, resourcesRegistry); } @@ -433,7 +418,10 @@ private static ResourcesRegistryImpl resourceRegistryImpl() { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { - ResourceConfigurationParser parser = new ResourceConfigurationParser(ImageSingletons.lookup(ResourcesRegistry.class), ConfigurationFiles.Options.StrictConfiguration.getValue()); + ConfigurationConditionResolver conditionResolver = new NativeImageConditionResolver(((FeatureImpl.BeforeAnalysisAccessImpl) access).getImageClassLoader(), + ClassInitializationSupport.singleton()); + ResourceConfigurationParser parser = new ResourceConfigurationParser<>(conditionResolver, ResourcesRegistry.singleton(), + ConfigurationFiles.Options.StrictConfiguration.getValue()); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurations(parser, imageClassLoader, "resource", ConfigurationFiles.Options.ResourceConfigurationFiles, ConfigurationFiles.Options.ResourceConfigurationResources, ConfigurationFile.RESOURCES.getFileName()); @@ -558,7 +546,7 @@ public void addResource(Module module, String resourceName) { @Override public void addResourceConditionally(Module module, String resourceName, ConfigurationCondition condition) { - access.registerReachabilityHandler(e -> addResource(module, resourceName), access.findClassByName(condition.getTypeName())); + access.registerReachabilityHandler(e -> addResource(module, resourceName), condition.getType()); } @Override diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ConfigurationParserUtils.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ConfigurationParserUtils.java index a16806ea2790..e9bd0fd71e56 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ConfigurationParserUtils.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ConfigurationParserUtils.java @@ -38,10 +38,10 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; +import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.ReflectionRegistry; -import jdk.graal.compiler.util.json.JSONParserException; -import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.ConfigurationParser; import com.oracle.svm.core.configure.ReflectionConfigurationParser; @@ -50,10 +50,14 @@ import com.oracle.svm.core.util.UserError; import com.oracle.svm.hosted.ImageClassLoader; +import jdk.graal.compiler.util.json.JSONParserException; + public final class ConfigurationParserUtils { - public static ReflectionConfigurationParser>> create(ReflectionRegistry registry, ImageClassLoader imageClassLoader) { - return new ReflectionConfigurationParser<>(RegistryAdapter.create(registry, imageClassLoader), + public static ReflectionConfigurationParser> create( + ConfigurationConditionResolver conditionResolver, ReflectionRegistry registry, ImageClassLoader imageClassLoader) { + return new ReflectionConfigurationParser<>(conditionResolver, + RegistryAdapter.create(registry, imageClassLoader), ConfigurationFiles.Options.StrictConfiguration.getValue(), ConfigurationFiles.Options.WarnAboutMissingReflectionOrJNIMetadataElements.getValue()); } 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 6b763eb4e8bd..2f2c5755e5bf 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 @@ -32,7 +32,6 @@ import org.graalvm.nativeimage.impl.RuntimeReflectionSupport; import com.oracle.svm.core.TypeResult; -import com.oracle.svm.core.configure.ConditionalElement; import com.oracle.svm.hosted.ImageClassLoader; public class ReflectionRegistryAdapter extends RegistryAdapter { @@ -44,8 +43,8 @@ public class ReflectionRegistryAdapter extends RegistryAdapter { } @Override - public TypeResult>> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) { - TypeResult>> result = super.resolveType(condition, typeName, allowPrimitives); + public TypeResult> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) { + TypeResult> result = super.resolveType(condition, typeName, allowPrimitives); if (!result.isPresent()) { Throwable classLookupException = result.getException(); if (classLookupException instanceof LinkageError) { @@ -58,72 +57,72 @@ public TypeResult>> resolveType(ConfigurationConditi } @Override - public void registerPublicClasses(ConditionalElement> type) { - reflectionSupport.registerAllClassesQuery(type.getCondition(), type.getElement()); + public void registerPublicClasses(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllClassesQuery(condition, type); } @Override - public void registerDeclaredClasses(ConditionalElement> type) { - reflectionSupport.registerAllDeclaredClassesQuery(type.getCondition(), type.getElement()); + public void registerDeclaredClasses(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllDeclaredClassesQuery(condition, type); } @Override - public void registerRecordComponents(ConditionalElement> type) { - reflectionSupport.registerAllRecordComponentsQuery(type.getCondition(), type.getElement()); + public void registerRecordComponents(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllRecordComponentsQuery(condition, type); } @Override - public void registerPermittedSubclasses(ConditionalElement> type) { - reflectionSupport.registerAllPermittedSubclassesQuery(type.getCondition(), type.getElement()); + public void registerPermittedSubclasses(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllPermittedSubclassesQuery(condition, type); } @Override - public void registerNestMembers(ConditionalElement> type) { - reflectionSupport.registerAllNestMembersQuery(type.getCondition(), type.getElement()); + public void registerNestMembers(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllNestMembersQuery(condition, type); } @Override - public void registerSigners(ConditionalElement> type) { - reflectionSupport.registerAllSignersQuery(type.getCondition(), type.getElement()); + public void registerSigners(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllSignersQuery(condition, type); } @Override - public void registerPublicFields(ConditionalElement> type) { - reflectionSupport.registerAllFieldsQuery(type.getCondition(), type.getElement()); + public void registerPublicFields(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllFieldsQuery(condition, type); } @Override - public void registerDeclaredFields(ConditionalElement> type) { - reflectionSupport.registerAllDeclaredFieldsQuery(type.getCondition(), type.getElement()); + public void registerDeclaredFields(ConfigurationCondition condition, Class type) { + reflectionSupport.registerAllDeclaredFieldsQuery(condition, type); } @Override - public void registerPublicMethods(boolean queriedOnly, ConditionalElement> type) { - reflectionSupport.registerAllMethodsQuery(type.getCondition(), queriedOnly, type.getElement()); + public void registerPublicMethods(ConfigurationCondition condition, boolean queriedOnly, Class type) { + reflectionSupport.registerAllMethodsQuery(condition, queriedOnly, type); } @Override - public void registerDeclaredMethods(boolean queriedOnly, ConditionalElement> type) { - reflectionSupport.registerAllDeclaredMethodsQuery(type.getCondition(), queriedOnly, type.getElement()); + public void registerDeclaredMethods(ConfigurationCondition condition, boolean queriedOnly, Class type) { + reflectionSupport.registerAllDeclaredMethodsQuery(condition, queriedOnly, type); } @Override - public void registerPublicConstructors(boolean queriedOnly, ConditionalElement> type) { - reflectionSupport.registerAllConstructorsQuery(type.getCondition(), queriedOnly, type.getElement()); + public void registerPublicConstructors(ConfigurationCondition condition, boolean queriedOnly, Class type) { + reflectionSupport.registerAllConstructorsQuery(condition, queriedOnly, type); } @Override - public void registerDeclaredConstructors(boolean queriedOnly, ConditionalElement> type) { - reflectionSupport.registerAllDeclaredConstructorsQuery(type.getCondition(), queriedOnly, type.getElement()); + public void registerDeclaredConstructors(ConfigurationCondition condition, boolean queriedOnly, Class type) { + reflectionSupport.registerAllDeclaredConstructorsQuery(condition, queriedOnly, type); } @Override - public void registerField(ConditionalElement> type, String fieldName, boolean allowWrite) throws NoSuchFieldException { + public void registerField(ConfigurationCondition condition, Class type, String fieldName, boolean allowWrite) throws NoSuchFieldException { try { - super.registerField(type, fieldName, allowWrite); + super.registerField(condition, type, fieldName, allowWrite); } catch (NoSuchFieldException e) { if (throwMissingRegistrationErrors()) { - reflectionSupport.registerFieldLookup(type.getCondition(), type.getElement(), fieldName); + reflectionSupport.registerFieldLookup(condition, type, fieldName); } else { throw e; } @@ -131,12 +130,12 @@ public void registerField(ConditionalElement> type, String fieldName, b } @Override - public void registerMethod(boolean queriedOnly, ConditionalElement> type, String methodName, List>> methodParameterTypes) throws NoSuchMethodException { + public void registerMethod(ConfigurationCondition condition, boolean queriedOnly, Class type, String methodName, List> methodParameterTypes) throws NoSuchMethodException { try { - super.registerMethod(queriedOnly, type, methodName, methodParameterTypes); + super.registerMethod(condition, queriedOnly, type, methodName, methodParameterTypes); } catch (NoSuchMethodException e) { if (throwMissingRegistrationErrors()) { - reflectionSupport.registerMethodLookup(type.getCondition(), type.getElement(), methodName, getParameterTypes(methodParameterTypes)); + reflectionSupport.registerMethodLookup(condition, type, methodName, getParameterTypes(methodParameterTypes)); } else { throw e; } @@ -144,12 +143,12 @@ public void registerMethod(boolean queriedOnly, ConditionalElement> typ } @Override - public void registerConstructor(boolean queriedOnly, ConditionalElement> type, List>> methodParameterTypes) throws NoSuchMethodException { + public void registerConstructor(ConfigurationCondition condition, boolean queriedOnly, Class type, List> methodParameterTypes) throws NoSuchMethodException { try { - super.registerConstructor(queriedOnly, type, methodParameterTypes); + super.registerConstructor(condition, queriedOnly, type, methodParameterTypes); } catch (NoSuchMethodException e) { if (throwMissingRegistrationErrors()) { - reflectionSupport.registerConstructorLookup(type.getCondition(), type.getElement(), getParameterTypes(methodParameterTypes)); + reflectionSupport.registerConstructorLookup(condition, type, getParameterTypes(methodParameterTypes)); } else { throw e; } 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 1725a1cc7752..18dcdeeaceaf 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 @@ -34,14 +34,13 @@ import org.graalvm.nativeimage.impl.RuntimeReflectionSupport; import com.oracle.svm.core.TypeResult; -import com.oracle.svm.core.configure.ConditionalElement; import com.oracle.svm.core.configure.ReflectionConfigurationParserDelegate; import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.util.ClassUtil; import jdk.vm.ci.meta.MetaUtil; -public class RegistryAdapter implements ReflectionConfigurationParserDelegate>> { +public class RegistryAdapter implements ReflectionConfigurationParserDelegate> { private final ReflectionRegistry registry; private final ImageClassLoader classLoader; @@ -59,26 +58,17 @@ public static RegistryAdapter create(ReflectionRegistry registry, ImageClassLoad } @Override - public void registerType(ConditionalElement> type) { - registry.register(type.getCondition(), type.getElement()); + public void registerType(ConfigurationCondition condition, Class type) { + registry.register(condition, type); } @Override - public TypeResult resolveCondition(String typeName) { - String canonicalizedName = canonicalizeTypeName(typeName); - TypeResult> clazz = classLoader.findClass(canonicalizedName); - return clazz.map(Class::getTypeName) - .map(ConfigurationCondition::create); - } - - @Override - public TypeResult>> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) { + public TypeResult> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) { String name = canonicalizeTypeName(typeName); - TypeResult> clazz = classLoader.findClass(name, allowPrimitives); - return clazz.map(c -> new ConditionalElement<>(condition, c)); + return classLoader.findClass(name, allowPrimitives); } - private static String canonicalizeTypeName(String typeName) { + public static String canonicalizeTypeName(String typeName) { String name = typeName; if (name.indexOf('[') != -1) { /* accept "int[][]", "java.lang.String[]" */ @@ -88,73 +78,73 @@ private static String canonicalizeTypeName(String typeName) { } @Override - public void registerPublicClasses(ConditionalElement> type) { - registry.register(type.getCondition(), type.getElement().getClasses()); + public void registerPublicClasses(ConfigurationCondition condition, Class type) { + registry.register(condition, type.getClasses()); } @Override - public void registerDeclaredClasses(ConditionalElement> type) { - registry.register(type.getCondition(), type.getElement().getDeclaredClasses()); + public void registerDeclaredClasses(ConfigurationCondition condition, Class type) { + registry.register(condition, type.getDeclaredClasses()); } @Override - public void registerRecordComponents(ConditionalElement> type) { + public void registerRecordComponents(ConfigurationCondition condition, Class type) { } @Override - public void registerPermittedSubclasses(ConditionalElement> type) { + public void registerPermittedSubclasses(ConfigurationCondition condition, Class type) { } @Override - public void registerNestMembers(ConditionalElement> type) { + public void registerNestMembers(ConfigurationCondition condition, Class type) { } @Override - public void registerSigners(ConditionalElement> type) { + public void registerSigners(ConfigurationCondition condition, Class type) { } @Override - public void registerPublicFields(ConditionalElement> type) { - registry.register(type.getCondition(), false, type.getElement().getFields()); + public void registerPublicFields(ConfigurationCondition condition, Class type) { + registry.register(condition, false, type.getFields()); } @Override - public void registerDeclaredFields(ConditionalElement> type) { - registry.register(type.getCondition(), false, type.getElement().getDeclaredFields()); + public void registerDeclaredFields(ConfigurationCondition condition, Class type) { + registry.register(condition, false, type.getDeclaredFields()); } @Override - public void registerPublicMethods(boolean queriedOnly, ConditionalElement> type) { - registry.register(type.getCondition(), queriedOnly, type.getElement().getMethods()); + public void registerPublicMethods(ConfigurationCondition condition, boolean queriedOnly, Class type) { + registry.register(condition, queriedOnly, type.getMethods()); } @Override - public void registerDeclaredMethods(boolean queriedOnly, ConditionalElement> type) { - registry.register(type.getCondition(), queriedOnly, type.getElement().getDeclaredMethods()); + public void registerDeclaredMethods(ConfigurationCondition condition, boolean queriedOnly, Class type) { + registry.register(condition, queriedOnly, type.getDeclaredMethods()); } @Override - public void registerPublicConstructors(boolean queriedOnly, ConditionalElement> type) { - registry.register(type.getCondition(), queriedOnly, type.getElement().getConstructors()); + public void registerPublicConstructors(ConfigurationCondition condition, boolean queriedOnly, Class type) { + registry.register(condition, queriedOnly, type.getConstructors()); } @Override - public void registerDeclaredConstructors(boolean queriedOnly, ConditionalElement> type) { - registry.register(type.getCondition(), queriedOnly, type.getElement().getDeclaredConstructors()); + public void registerDeclaredConstructors(ConfigurationCondition condition, boolean queriedOnly, Class type) { + registry.register(condition, queriedOnly, type.getDeclaredConstructors()); } @Override - public void registerField(ConditionalElement> type, String fieldName, boolean allowWrite) throws NoSuchFieldException { - registry.register(type.getCondition(), allowWrite, type.getElement().getDeclaredField(fieldName)); + public void registerField(ConfigurationCondition condition, Class type, String fieldName, boolean allowWrite) throws NoSuchFieldException { + registry.register(condition, allowWrite, type.getDeclaredField(fieldName)); } @Override - public boolean registerAllMethodsWithName(boolean queriedOnly, ConditionalElement> type, String methodName) { + public boolean registerAllMethodsWithName(ConfigurationCondition condition, boolean queriedOnly, Class type, String methodName) { boolean found = false; - Executable[] methods = type.getElement().getDeclaredMethods(); + Executable[] methods = type.getDeclaredMethods(); for (Executable method : methods) { if (method.getName().equals(methodName)) { - registerExecutable(type.getCondition(), queriedOnly, method); + registerExecutable(condition, queriedOnly, method); found = true; } } @@ -162,17 +152,16 @@ public boolean registerAllMethodsWithName(boolean queriedOnly, ConditionalElemen } @Override - public boolean registerAllConstructors(boolean queriedOnly, ConditionalElement> type) { - Executable[] methods = type.getElement().getDeclaredConstructors(); - registerExecutable(type.getCondition(), queriedOnly, methods); + public boolean registerAllConstructors(ConfigurationCondition condition, boolean queriedOnly, Class type) { + Executable[] methods = type.getDeclaredConstructors(); + registerExecutable(condition, queriedOnly, methods); return methods.length > 0; } @Override - public void registerUnsafeAllocated(ConditionalElement> clazz) { - Class type = clazz.getElement(); - if (!type.isArray() && !type.isInterface() && !Modifier.isAbstract(type.getModifiers())) { - registry.register(clazz.getCondition(), true, clazz.getElement()); + public void registerUnsafeAllocated(ConfigurationCondition condition, Class clazz) { + if (!clazz.isArray() && !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers())) { + registry.register(condition, true, clazz); /* * Ignore otherwise as the implementation of allocateInstance will anyhow throw an * exception. @@ -181,11 +170,11 @@ public void registerUnsafeAllocated(ConditionalElement> clazz) { } @Override - public void registerMethod(boolean queriedOnly, ConditionalElement> type, String methodName, List>> methodParameterTypes) throws NoSuchMethodException { + public void registerMethod(ConfigurationCondition condition, boolean queriedOnly, Class type, String methodName, List> methodParameterTypes) throws NoSuchMethodException { Class[] parameterTypesArray = getParameterTypes(methodParameterTypes); Method method; try { - method = type.getElement().getDeclaredMethod(methodName, parameterTypesArray); + method = type.getDeclaredMethod(methodName, parameterTypesArray); } catch (NoClassDefFoundError e) { /* * getDeclaredMethod() builds a set of all the declared methods, which can fail when a @@ -196,24 +185,22 @@ public void registerMethod(boolean queriedOnly, ConditionalElement> typ * precisely because the application used getMethod() instead of getDeclaredMethod(). */ try { - method = type.getElement().getMethod(methodName, parameterTypesArray); + method = type.getMethod(methodName, parameterTypesArray); } catch (Throwable ignored) { throw e; } } - registerExecutable(type.getCondition(), queriedOnly, method); + registerExecutable(condition, queriedOnly, method); } @Override - public void registerConstructor(boolean queriedOnly, ConditionalElement> type, List>> methodParameterTypes) throws NoSuchMethodException { + public void registerConstructor(ConfigurationCondition condition, boolean queriedOnly, Class type, List> methodParameterTypes) throws NoSuchMethodException { Class[] parameterTypesArray = getParameterTypes(methodParameterTypes); - registerExecutable(type.getCondition(), queriedOnly, type.getElement().getDeclaredConstructor(parameterTypesArray)); + registerExecutable(condition, queriedOnly, type.getDeclaredConstructor(parameterTypesArray)); } - static Class[] getParameterTypes(List>> methodParameterTypes) { - return methodParameterTypes.stream() - .map(ConditionalElement::getElement) - .toArray(Class[]::new); + static Class[] getParameterTypes(List> methodParameterTypes) { + return methodParameterTypes.toArray(Class[]::new); } private void registerExecutable(ConfigurationCondition condition, boolean queriedOnly, Executable... executable) { @@ -221,12 +208,12 @@ private void registerExecutable(ConfigurationCondition condition, boolean querie } @Override - public String getTypeName(ConditionalElement> type) { - return type.getElement().getTypeName(); + public String getTypeName(Class type) { + return type.getTypeName(); } @Override - public String getSimpleName(ConditionalElement> type) { - return ClassUtil.getUnqualifiedName(type.getElement()); + public String getSimpleName(Class type) { + return ClassUtil.getUnqualifiedName(type); } } diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java index ba9315d8dd8b..c358226241e7 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JmxServerFeature.java @@ -77,7 +77,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } private static void registerJMXAgentResources() { - ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); + ResourcesRegistry resourcesRegistry = ResourcesRegistry.singleton(); resourcesRegistry.addResourceBundles(ConfigurationCondition.alwaysTrue(), "jdk.internal.agent.resources.agent"); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java index d2ad28b3825e..60a75e6f05a3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java @@ -59,7 +59,7 @@ import com.oracle.graal.pointsto.meta.AnalysisType; import com.oracle.graal.pointsto.meta.AnalysisUniverse; import com.oracle.svm.core.config.ObjectLayout; -import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.ReflectionConfigurationParser; @@ -83,6 +83,7 @@ import com.oracle.svm.hosted.FeatureImpl.CompilationAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.ProgressReporter; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.code.CEntryPointData; import com.oracle.svm.hosted.code.FactoryMethodSupport; import com.oracle.svm.hosted.config.ConfigurationParserUtils; @@ -95,6 +96,7 @@ import com.oracle.svm.hosted.meta.HostedUniverse; import com.oracle.svm.hosted.meta.KnownOffsetsFeature; import com.oracle.svm.hosted.meta.MaterializedConstantFields; +import com.oracle.svm.hosted.reflect.NativeImageConditionResolver; import com.oracle.svm.hosted.substitute.SubstitutionReflectivityFilter; import com.oracle.svm.util.ReflectionUtil; @@ -194,7 +196,9 @@ public void afterRegistration(AfterRegistrationAccess arg) { runtimeSupport = new JNIRuntimeAccessibilitySupportImpl(); ImageSingletons.add(RuntimeJNIAccessSupport.class, runtimeSupport); - ReflectionConfigurationParser>> parser = ConfigurationParserUtils.create(runtimeSupport, access.getImageClassLoader()); + ConfigurationConditionResolver conditionResolver = new NativeImageConditionResolver(access.getImageClassLoader(), + ClassInitializationSupport.singleton()); + ReflectionConfigurationParser> parser = ConfigurationParserUtils.create(conditionResolver, runtimeSupport, access.getImageClassLoader()); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurations(parser, access.getImageClassLoader(), "JNI", ConfigurationFiles.Options.JNIConfigurationFiles, ConfigurationFiles.Options.JNIConfigurationResources, ConfigurationFile.JNI.getFileName()); } @@ -207,21 +211,21 @@ public void register(ConfigurationCondition condition, boolean unsafeAllocated, assert !unsafeAllocated : "unsafeAllocated can be only set via Unsafe.allocateInstance, not via JNI."; Objects.requireNonNull(clazz, () -> nullErrorMessage("class")); abortIfSealed(); - registerConditionalConfiguration(condition, () -> newClasses.add(clazz)); + registerConditionalConfiguration(condition, (cnd) -> newClasses.add(clazz)); } @Override public void register(ConfigurationCondition condition, boolean queriedOnly, Executable... executables) { requireNonNull(executables, "executable"); abortIfSealed(); - registerConditionalConfiguration(condition, () -> newMethods.addAll(Arrays.asList(executables))); + registerConditionalConfiguration(condition, (cnd) -> newMethods.addAll(Arrays.asList(executables))); } @Override public void register(ConfigurationCondition condition, boolean finalIsWritable, Field... fields) { requireNonNull(fields, "field"); abortIfSealed(); - registerConditionalConfiguration(condition, () -> registerFields(finalIsWritable, fields)); + registerConditionalConfiguration(condition, (cnd) -> registerFields(finalIsWritable, fields)); } private void registerFields(boolean finalIsWritable, Field[] fields) { 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 new file mode 100644 index 000000000000..99736dc84a7d --- /dev/null +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/NativeImageConditionResolver.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.hosted.reflect; + +import org.graalvm.nativeimage.impl.ConfigurationCondition; +import org.graalvm.nativeimage.impl.UnresolvedConfigurationCondition; + +import com.oracle.svm.core.TypeResult; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; +import com.oracle.svm.hosted.ImageClassLoader; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; +import com.oracle.svm.hosted.config.RegistryAdapter; + +public class NativeImageConditionResolver implements ConfigurationConditionResolver { + private final ImageClassLoader classLoader; + @SuppressWarnings({"FieldCanBeLocal", "unused"}) private final ClassInitializationSupport classInitializationSupport; + + public NativeImageConditionResolver(ImageClassLoader classLoader, ClassInitializationSupport classInitializationSupport) { + this.classLoader = classLoader; + this.classInitializationSupport = classInitializationSupport; + } + + @Override + public TypeResult resolveCondition(UnresolvedConfigurationCondition unresolvedCondition) { + String canonicalizedName = RegistryAdapter.canonicalizeTypeName(unresolvedCondition.getTypeName()); + TypeResult> clazz = classLoader.findClass(canonicalizedName); + return clazz.map(ConfigurationCondition::create); + } + + @Override + public ConfigurationCondition alwaysTrue() { + return ConfigurationCondition.alwaysTrue(); + } +} diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java index 16844f504757..d1f810ee1a0c 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java @@ -104,6 +104,7 @@ public class ReflectionDataBuilder extends ConditionalConfigurationRegistry impl private AnalysisUniverse universe; private final SubstrateAnnotationExtractor annotationExtractor; private BeforeAnalysisAccessImpl analysisAccess; + private boolean sealed; // Reflection data @@ -183,13 +184,13 @@ public void register(ConfigurationCondition condition, boolean unsafeInstantiate Objects.requireNonNull(clazz, () -> nullErrorMessage("class")); checkNotSealed(); register(analysisUniverse -> registerConditionalConfiguration(condition, - () -> analysisUniverse.getBigbang().postTask(debug -> registerClass(clazz, unsafeInstantiated, true)))); + (cnd) -> analysisUniverse.getBigbang().postTask(debug -> registerClass(clazz, unsafeInstantiated, true)))); } @Override public void registerAllClassesQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_CLASSES_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_CLASSES_FLAG)); try { for (Class innerClass : clazz.getClasses()) { innerClasses.computeIfAbsent(innerClass.getDeclaringClass(), c -> ConcurrentHashMap.newKeySet()).add(innerClass); @@ -203,7 +204,7 @@ public void registerAllClassesQuery(ConfigurationCondition condition, Class c @Override public void registerAllDeclaredClassesQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_DECLARED_CLASSES_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_DECLARED_CLASSES_FLAG)); try { for (Class innerClass : clazz.getDeclaredClasses()) { innerClasses.computeIfAbsent(clazz, c -> ConcurrentHashMap.newKeySet()).add(innerClass); @@ -251,7 +252,7 @@ private void registerClass(Class clazz, boolean unsafeInstantiated, boolean a @Override public void registerClassLookupException(ConfigurationCondition condition, String typeName, Throwable t) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> ClassForNameSupport.registerExceptionForClass(typeName, t)); + registerConditionalConfiguration(condition, (cnd) -> ClassForNameSupport.registerExceptionForClass(typeName, t)); } @Override @@ -260,7 +261,7 @@ public void registerClassLookup(ConfigurationCondition condition, String typeNam try { register(condition, Class.forName(typeName, false, ClassLoader.getSystemClassLoader())); } catch (ClassNotFoundException e) { - registerConditionalConfiguration(condition, () -> ClassForNameSupport.registerNegativeQuery(typeName)); + registerConditionalConfiguration(condition, (cnd) -> ClassForNameSupport.registerNegativeQuery(typeName)); } catch (Throwable t) { registerClassLookupException(condition, typeName, t); } @@ -269,15 +270,15 @@ public void registerClassLookup(ConfigurationCondition condition, String typeNam @Override public void registerAllRecordComponentsQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_RECORD_COMPONENTS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_RECORD_COMPONENTS_FLAG)); register(analysisUniverse -> registerConditionalConfiguration(condition, - () -> analysisUniverse.getBigbang().postTask(debug -> registerRecordComponents(clazz)))); + (cnd) -> analysisUniverse.getBigbang().postTask(debug -> registerRecordComponents(clazz)))); } @Override public void registerAllPermittedSubclassesQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { setQueryFlag(clazz, ALL_PERMITTED_SUBCLASSES_FLAG); if (clazz.isSealed()) { register(condition, clazz.getPermittedSubclasses()); @@ -288,11 +289,11 @@ public void registerAllPermittedSubclassesQuery(ConfigurationCondition condition @Override public void registerAllNestMembersQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { setQueryFlag(clazz, ALL_NEST_MEMBERS_FLAG); for (Class nestMember : clazz.getNestMembers()) { if (nestMember != clazz) { - register(condition, nestMember); + register(cnd, nestMember); } } }); @@ -301,7 +302,7 @@ public void registerAllNestMembersQuery(ConfigurationCondition condition, Class< @Override public void registerAllSignersQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { setQueryFlag(clazz, ALL_SIGNERS_FLAG); Object[] signers = clazz.getSigners(); if (signers != null) { @@ -316,7 +317,7 @@ public void registerAllSignersQuery(ConfigurationCondition condition, Class c public void register(ConfigurationCondition condition, boolean queriedOnly, Executable... executables) { requireNonNull(executables, "executable"); checkNotSealed(); - register(analysisUniverse -> registerConditionalConfiguration(condition, () -> { + register(analysisUniverse -> registerConditionalConfiguration(condition, (cnd) -> { for (Executable executable : executables) { analysisUniverse.getBigbang().postTask(debug -> registerMethod(queriedOnly, executable)); } @@ -328,7 +329,7 @@ public void registerAllMethodsQuery(ConfigurationCondition condition, boolean qu checkNotSealed(); for (Class current = clazz; current != null; current = current.getSuperclass()) { final Class currentLambda = current; - registerConditionalConfiguration(condition, () -> setQueryFlag(currentLambda, ALL_METHODS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(currentLambda, ALL_METHODS_FLAG)); } try { register(condition, queriedOnly, clazz.getMethods()); @@ -340,7 +341,7 @@ public void registerAllMethodsQuery(ConfigurationCondition condition, boolean qu @Override public void registerAllDeclaredMethodsQuery(ConfigurationCondition condition, boolean queriedOnly, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_DECLARED_METHODS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_DECLARED_METHODS_FLAG)); try { register(condition, queriedOnly, clazz.getDeclaredMethods()); } catch (LinkageError e) { @@ -353,7 +354,7 @@ public void registerAllConstructorsQuery(ConfigurationCondition condition, boole checkNotSealed(); for (Class current = clazz; current != null; current = current.getSuperclass()) { final Class currentLambda = current; - registerConditionalConfiguration(condition, () -> setQueryFlag(currentLambda, ALL_CONSTRUCTORS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(currentLambda, ALL_CONSTRUCTORS_FLAG)); } try { register(condition, queriedOnly, clazz.getConstructors()); @@ -365,7 +366,7 @@ public void registerAllConstructorsQuery(ConfigurationCondition condition, boole @Override public void registerAllDeclaredConstructorsQuery(ConfigurationCondition condition, boolean queriedOnly, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_DECLARED_CONSTRUCTORS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_DECLARED_CONSTRUCTORS_FLAG)); try { register(condition, queriedOnly, clazz.getDeclaredConstructors()); } catch (LinkageError e) { @@ -424,7 +425,7 @@ public void registerMethodLookup(ConfigurationCondition condition, Class decl try { register(condition, true, declaringClass.getDeclaredMethod(methodName, parameterTypes)); } catch (NoSuchMethodException e) { - registerConditionalConfiguration(condition, () -> negativeMethodLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) + registerConditionalConfiguration(condition, (cnd) -> negativeMethodLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) .add(new AnalysisMethod.Signature(methodName, metaAccess.lookupJavaTypes(parameterTypes)))); } } @@ -436,7 +437,7 @@ public void registerConstructorLookup(ConfigurationCondition condition, Class register(condition, true, declaringClass.getDeclaredConstructor(parameterTypes)); } catch (NoSuchMethodException e) { registerConditionalConfiguration(condition, - () -> negativeConstructorLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) + (cnd) -> negativeConstructorLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()) .add(metaAccess.lookupJavaTypes(parameterTypes))); } } @@ -449,7 +450,7 @@ public void register(ConfigurationCondition condition, boolean finalIsWritable, } private void registerInternal(ConfigurationCondition condition, Field... fields) { - register(analysisUniverse -> registerConditionalConfiguration(condition, () -> { + register(analysisUniverse -> registerConditionalConfiguration(condition, (cnd) -> { for (Field field : fields) { analysisUniverse.getBigbang().postTask(debug -> registerField(field)); } @@ -461,7 +462,7 @@ public void registerAllFieldsQuery(ConfigurationCondition condition, Class cl checkNotSealed(); for (Class current = clazz; current != null; current = current.getSuperclass()) { final Class currentLambda = current; - registerConditionalConfiguration(condition, () -> setQueryFlag(currentLambda, ALL_FIELDS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(currentLambda, ALL_FIELDS_FLAG)); } try { registerInternal(condition, clazz.getFields()); @@ -473,7 +474,7 @@ public void registerAllFieldsQuery(ConfigurationCondition condition, Class cl @Override public void registerAllDeclaredFieldsQuery(ConfigurationCondition condition, Class clazz) { checkNotSealed(); - registerConditionalConfiguration(condition, () -> setQueryFlag(clazz, ALL_DECLARED_FIELDS_FLAG)); + registerConditionalConfiguration(condition, (cnd) -> setQueryFlag(clazz, ALL_DECLARED_FIELDS_FLAG)); try { registerInternal(condition, clazz.getDeclaredFields()); } catch (LinkageError e) { @@ -511,7 +512,8 @@ public void registerFieldLookup(ConfigurationCondition condition, Class decla try { registerInternal(condition, declaringClass.getDeclaredField(fieldName)); } catch (NoSuchFieldException e) { - registerConditionalConfiguration(condition, () -> negativeFieldLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()).add(fieldName)); + registerConditionalConfiguration(condition, + (cnd) -> negativeFieldLookups.computeIfAbsent(metaAccess.lookupJavaType(declaringClass), (key) -> ConcurrentHashMap.newKeySet()).add(fieldName)); } } @@ -529,7 +531,8 @@ private void processAnnotationMethod(boolean queriedOnly, Method method) { Class annotationClass = method.getDeclaringClass(); Class proxyClass = Proxy.getProxyClass(annotationClass.getClassLoader(), annotationClass); try { - register(ConfigurationCondition.create(proxyClass.getTypeName()), queriedOnly, proxyClass.getDeclaredMethod(method.getName(), method.getParameterTypes())); + var condition = ConfigurationCondition.create(proxyClass); + register(condition, queriedOnly, proxyClass.getDeclaredMethod(method.getName(), method.getParameterTypes())); } catch (NoSuchMethodException e) { /* * The annotation member is not present in the proxy class so we don't add it. @@ -542,7 +545,8 @@ private void processAnnotationField(Field field) { Class annotationClass = field.getDeclaringClass(); Class proxyClass = Proxy.getProxyClass(annotationClass.getClassLoader(), annotationClass); try { - register(ConfigurationCondition.create(proxyClass.getTypeName()), false, proxyClass.getDeclaredField(field.getName())); + var condition = ConfigurationCondition.create(proxyClass); + register(condition, false, proxyClass.getDeclaredField(field.getName())); } catch (NoSuchFieldException e) { /* * The annotation member is not present in the proxy class so we don't add it. 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 2277fd9418c1..ea11cafe4f82 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 @@ -41,6 +41,7 @@ import org.graalvm.nativeimage.c.function.CFunctionPointer; import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.AnnotationExtractor; +import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeReflectionSupport; import com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess; @@ -49,7 +50,6 @@ import com.oracle.svm.core.ParsingReason; import com.oracle.svm.core.SubstrateUtil; import com.oracle.svm.core.annotate.Delete; -import com.oracle.svm.core.configure.ConditionalElement; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.ReflectionConfigurationParser; @@ -75,6 +75,7 @@ import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.hosted.analysis.Inflation; import com.oracle.svm.hosted.annotation.SubstrateAnnotationExtractor; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.code.FactoryMethodSupport; import com.oracle.svm.hosted.config.ConfigurationParserUtils; import com.oracle.svm.hosted.meta.HostedField; @@ -259,9 +260,9 @@ public void afterRegistration(AfterRegistrationAccess access) { public void duringSetup(DuringSetupAccess a) { DuringSetupAccessImpl access = (DuringSetupAccessImpl) a; aUniverse = access.getUniverse(); + var conditionResolver = new NativeImageConditionResolver(access.getImageClassLoader(), ClassInitializationSupport.singleton()); reflectionData.duringSetup(access.getMetaAccess(), aUniverse); - - ReflectionConfigurationParser>> parser = ConfigurationParserUtils.create(reflectionData, access.getImageClassLoader()); + ReflectionConfigurationParser> parser = ConfigurationParserUtils.create(conditionResolver, reflectionData, access.getImageClassLoader()); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurations(parser, access.getImageClassLoader(), "reflection", ConfigurationFiles.Options.ReflectionConfigurationFiles, ConfigurationFiles.Options.ReflectionConfigurationResources, ConfigurationFile.REFLECTION.getFileName()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/DynamicProxyFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/DynamicProxyFeature.java index 3caa69ae79f8..6dc88f832362 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/DynamicProxyFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/DynamicProxyFeature.java @@ -30,8 +30,10 @@ import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeProxyCreationSupport; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.ProxyConfigurationParser; @@ -39,12 +41,13 @@ import com.oracle.svm.core.feature.InternalFeature; import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; import com.oracle.svm.core.reflect.proxy.DynamicProxySupport; -import com.oracle.svm.hosted.ConfigurationTypeResolver; import com.oracle.svm.hosted.FallbackFeature; import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl; import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl; import com.oracle.svm.hosted.ImageClassLoader; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.config.ConfigurationParserUtils; +import com.oracle.svm.hosted.reflect.NativeImageConditionResolver; import com.oracle.svm.hosted.reflect.ReflectionFeature; @AutomaticallyRegisteredFeature @@ -62,13 +65,13 @@ public void duringSetup(DuringSetupAccess a) { DuringSetupAccessImpl access = (DuringSetupAccessImpl) a; ImageClassLoader imageClassLoader = access.getImageClassLoader(); + ConfigurationConditionResolver conditionResolver = new NativeImageConditionResolver(imageClassLoader, ClassInitializationSupport.singleton()); DynamicProxySupport dynamicProxySupport = new DynamicProxySupport(); ImageSingletons.add(DynamicProxyRegistry.class, dynamicProxySupport); ImageSingletons.add(RuntimeProxyCreationSupport.class, dynamicProxySupport); - ConfigurationTypeResolver typeResolver = new ConfigurationTypeResolver("resource configuration", imageClassLoader); - ProxyRegistry proxyRegistry = new ProxyRegistry(typeResolver, dynamicProxySupport, imageClassLoader); + ProxyRegistry proxyRegistry = new ProxyRegistry(dynamicProxySupport, imageClassLoader); ImageSingletons.add(ProxyRegistry.class, proxyRegistry); - ProxyConfigurationParser parser = new ProxyConfigurationParser(proxyRegistry, ConfigurationFiles.Options.StrictConfiguration.getValue()); + ProxyConfigurationParser parser = new ProxyConfigurationParser<>(conditionResolver, ConfigurationFiles.Options.StrictConfiguration.getValue(), proxyRegistry); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurations(parser, imageClassLoader, "dynamic proxy", ConfigurationFiles.Options.DynamicProxyConfigurationFiles, ConfigurationFiles.Options.DynamicProxyConfigurationResources, ConfigurationFile.DYNAMIC_PROXY.getFileName()); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/ProxyRegistry.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/ProxyRegistry.java index 82794c408f11..525fd02273b9 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/ProxyRegistry.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/proxy/ProxyRegistry.java @@ -25,38 +25,36 @@ package com.oracle.svm.hosted.reflect.proxy; import java.util.List; -import java.util.function.Consumer; +import java.util.function.BiConsumer; + +import org.graalvm.nativeimage.impl.ConfigurationCondition; -import com.oracle.svm.core.configure.ConditionalElement; import com.oracle.svm.core.jdk.proxy.DynamicProxyRegistry; import com.oracle.svm.hosted.ConditionalConfigurationRegistry; -import com.oracle.svm.hosted.ConfigurationTypeResolver; import com.oracle.svm.hosted.ImageClassLoader; import com.oracle.svm.util.LogUtils; -public class ProxyRegistry extends ConditionalConfigurationRegistry implements Consumer>> { - private final ConfigurationTypeResolver typeResolver; +public class ProxyRegistry extends ConditionalConfigurationRegistry implements BiConsumer> { private final DynamicProxyRegistry dynamicProxySupport; private final ImageClassLoader imageClassLoader; - public ProxyRegistry(ConfigurationTypeResolver typeResolver, DynamicProxyRegistry dynamicProxySupport, ImageClassLoader imageClassLoader) { - this.typeResolver = typeResolver; + public ProxyRegistry(DynamicProxyRegistry dynamicProxySupport, ImageClassLoader imageClassLoader) { this.dynamicProxySupport = dynamicProxySupport; this.imageClassLoader = imageClassLoader; } @Override - public void accept(ConditionalElement> proxies) { + public void accept(ConfigurationCondition condition, List proxies) { Class[] interfaces = checkIfInterfacesAreValid(proxies); if (interfaces != null) { - registerConditionalConfiguration(proxies.getCondition(), () -> { + registerConditionalConfiguration(condition, (cnd) -> { /* The interfaces array can be empty. The java.lang.reflect.Proxy API allows it. */ dynamicProxySupport.addProxyClass(interfaces); }); } } - public Class createProxyClassForSerialization(ConditionalElement> proxies) { + public Class createProxyClassForSerialization(List proxies) { Class[] interfaces = checkIfInterfacesAreValid(proxies); if (interfaces != null) { return dynamicProxySupport.createProxyClassForSerialization(interfaces); @@ -65,16 +63,12 @@ public Class createProxyClassForSerialization(ConditionalElement return null; } - private Class[] checkIfInterfacesAreValid(ConditionalElement> proxies) { - if (typeResolver.resolveConditionType(proxies.getCondition().getTypeName()) == null) { - return null; - } - List interfaceNames = proxies.getElement(); - Class[] interfaces = new Class[interfaceNames.size()]; - for (int i = 0; i < interfaceNames.size(); i++) { - String className = interfaceNames.get(i); - Class clazz = imageClassLoader.findClass(className).get(); - if (!checkClass(interfaceNames, className, clazz)) { + private Class[] checkIfInterfacesAreValid(List proxyInterfaceNames) { + Class[] interfaces = new Class[proxyInterfaceNames.size()]; + for (int i = 0; i < proxyInterfaceNames.size(); i++) { + String interfaceName = proxyInterfaceNames.get(i); + Class clazz = imageClassLoader.findClass(interfaceName).get(); + if (!checkClass(proxyInterfaceNames, interfaceName, clazz)) { return null; } interfaces[i] = clazz; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java index 1cc2dcaa5539..9e87866535ba 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/serialize/SerializationFeature.java @@ -57,7 +57,7 @@ import com.oracle.graal.pointsto.phases.NoClassInitializationPlugin; import com.oracle.graal.pointsto.util.GraalAccess; -import com.oracle.svm.core.configure.ConditionalElement; +import com.oracle.svm.core.configure.ConfigurationConditionResolver; import com.oracle.svm.core.configure.ConfigurationFile; import com.oracle.svm.core.configure.ConfigurationFiles; import com.oracle.svm.core.configure.SerializationConfigurationParser; @@ -72,7 +72,9 @@ import com.oracle.svm.hosted.FallbackFeature; import com.oracle.svm.hosted.FeatureImpl; import com.oracle.svm.hosted.ImageClassLoader; +import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; import com.oracle.svm.hosted.config.ConfigurationParserUtils; +import com.oracle.svm.hosted.reflect.NativeImageConditionResolver; import com.oracle.svm.hosted.reflect.RecordUtils; import com.oracle.svm.hosted.reflect.ReflectionFeature; import com.oracle.svm.hosted.reflect.proxy.DynamicProxyFeature; @@ -121,17 +123,20 @@ public List> getRequiredFeatures() { public void duringSetup(DuringSetupAccess a) { FeatureImpl.DuringSetupAccessImpl access = (FeatureImpl.DuringSetupAccessImpl) a; ImageClassLoader imageClassLoader = access.getImageClassLoader(); + ConfigurationConditionResolver conditionResolver = new NativeImageConditionResolver(imageClassLoader, ClassInitializationSupport.singleton()); ConfigurationTypeResolver typeResolver = new ConfigurationTypeResolver("serialization configuration", imageClassLoader); SerializationDenyRegistry serializationDenyRegistry = new SerializationDenyRegistry(typeResolver); serializationBuilder = new SerializationBuilder(serializationDenyRegistry, access, typeResolver, ImageSingletons.lookup(ProxyRegistry.class)); ImageSingletons.add(RuntimeSerializationSupport.class, serializationBuilder); - SerializationConfigurationParser denyCollectorParser = new SerializationConfigurationParser(serializationDenyRegistry, ConfigurationFiles.Options.StrictConfiguration.getValue()); + SerializationConfigurationParser denyCollectorParser = new SerializationConfigurationParser<>(conditionResolver, serializationDenyRegistry, + ConfigurationFiles.Options.StrictConfiguration.getValue()); ConfigurationParserUtils.parseAndRegisterConfigurations(denyCollectorParser, imageClassLoader, "serialization", ConfigurationFiles.Options.SerializationDenyConfigurationFiles, ConfigurationFiles.Options.SerializationDenyConfigurationResources, ConfigurationFile.SERIALIZATION_DENY.getFileName()); - SerializationConfigurationParser parser = new SerializationConfigurationParser(serializationBuilder, ConfigurationFiles.Options.StrictConfiguration.getValue()); + SerializationConfigurationParser parser = new SerializationConfigurationParser<>(conditionResolver, serializationBuilder, + ConfigurationFiles.Options.StrictConfiguration.getValue()); loadedConfigurations = ConfigurationParserUtils.parseAndRegisterConfigurations(parser, imageClassLoader, "serialization", ConfigurationFiles.Options.SerializationConfigurationFiles, ConfigurationFiles.Options.SerializationConfigurationResources, ConfigurationFile.SERIALIZATION.getFileName()); @@ -297,7 +302,7 @@ private static Stream allExecutablesDeclaredInClas } } -final class SerializationDenyRegistry implements RuntimeSerializationSupport { +final class SerializationDenyRegistry implements RuntimeSerializationSupport { private final Map, Boolean> deniedClasses = new HashMap<>(); private final ConfigurationTypeResolver typeResolver; @@ -356,7 +361,7 @@ public boolean isAllowed(Class clazz) { } } -final class SerializationBuilder extends ConditionalConfigurationRegistry implements RuntimeSerializationSupport { +final class SerializationBuilder extends ConditionalConfigurationRegistry implements RuntimeSerializationSupport { private static final Method getConstructorAccessorMethod = ReflectionUtil.lookupMethod(Constructor.class, "getConstructorAccessor"); private static final Method getExternalizableConstructorMethod = ReflectionUtil.lookupMethod(ObjectStreamClass.class, "getExternalizableConstructor", Class.class); @@ -460,11 +465,6 @@ public void register(ConfigurationCondition condition, Class... classes) { public void registerLambdaCapturingClass(ConfigurationCondition condition, String lambdaCapturingClassName) { abortIfSealed(); - Class conditionClass = typeResolver.resolveConditionType(condition.getTypeName()); - if (conditionClass == null) { - return; - } - Class lambdaCapturingClass = typeResolver.resolveType(lambdaCapturingClassName); if (lambdaCapturingClass == null || lambdaCapturingClass.isPrimitive() || lambdaCapturingClass.isArray()) { return; @@ -475,7 +475,7 @@ public void registerLambdaCapturingClass(ConfigurationCondition condition, Strin return; } - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { ImageSingletons.lookup(SerializationFeature.class).capturingClasses.add(lambdaCapturingClass); RuntimeReflection.register(lambdaCapturingClass); RuntimeReflection.register(ReflectionUtil.lookupMethod(lambdaCapturingClass, "$deserializeLambda$", SerializedLambda.class)); @@ -484,19 +484,15 @@ public void registerLambdaCapturingClass(ConfigurationCondition condition, Strin @Override public void registerProxyClass(ConfigurationCondition condition, List implementedInterfaces) { - Class proxyClass = proxyRegistry.createProxyClassForSerialization(new ConditionalElement<>(condition, implementedInterfaces)); - registerWithTargetConstructorClass(ConfigurationCondition.alwaysTrue(), proxyClass, Object.class); + registerConditionalConfiguration(condition, (cnd) -> { + Class proxyClass = proxyRegistry.createProxyClassForSerialization(implementedInterfaces); + registerWithTargetConstructorClass(ConfigurationCondition.alwaysTrue(), proxyClass, Object.class); + }); } @Override public void registerWithTargetConstructorClass(ConfigurationCondition condition, String targetClassName, String customTargetConstructorClassName) { abortIfSealed(); - - Class conditionClass = typeResolver.resolveConditionType(condition.getTypeName()); - if (conditionClass == null) { - return; - } - Class serializationTargetClass = typeResolver.resolveType(targetClassName); /* With invalid streams we have to register the class for lookup */ ImageSingletons.lookup(RuntimeReflectionSupport.class).registerClassLookup(condition, targetClassName); @@ -518,14 +514,8 @@ public void registerWithTargetConstructorClass(ConfigurationCondition condition, @Override public void registerWithTargetConstructorClass(ConfigurationCondition condition, Class serializationTargetClass, Class customTargetConstructorClass) { abortIfSealed(); - - Class conditionClass = typeResolver.resolveConditionType(condition.getTypeName()); - if (conditionClass == null) { - return; - } /* - * Register class for reflection as the it is needed when the class-value itself is - * serialized. + * Register class for reflection as it is needed when the class-value itself is serialized. */ ImageSingletons.lookup(RuntimeReflectionSupport.class).register(condition, serializationTargetClass); @@ -549,7 +539,7 @@ public void registerWithTargetConstructorClass(ConfigurationCondition condition, return; } } - registerConditionalConfiguration(condition, () -> { + registerConditionalConfiguration(condition, (cnd) -> { Optional.ofNullable(addConstructorAccessor(serializationTargetClass, customTargetConstructorClass)) .map(ReflectionUtil::lookupConstructor) .ifPresent(RuntimeReflection::register); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/xml/XMLParsersRegistration.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/xml/XMLParsersRegistration.java index 13940b2be407..995db3578688 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/xml/XMLParsersRegistration.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/xml/XMLParsersRegistration.java @@ -34,8 +34,8 @@ import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.ConfigurationCondition; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; -import org.graalvm.nativeimage.impl.RuntimeResourceSupport; +import com.oracle.svm.core.configure.ResourcesRegistry; import com.oracle.svm.core.jdk.JNIRegistrationUtil; import com.oracle.svm.hosted.FeatureImpl; import com.oracle.svm.hosted.classinitialization.ClassInitializationSupport; @@ -133,22 +133,22 @@ void registerResources() { ClassInitializationSupport classInitializationSupport = (ClassInitializationSupport) ImageSingletons.lookup(RuntimeClassInitializationSupport.class); classInitializationSupport.setConfigurationSealed(false); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.Encodings"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.HTMLEntities"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.XMLEntities"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.xpath.regex.message"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.DOMMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.DatatypeMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.JAXPValidationMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.SAXMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XIncludeMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLSchemaMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLSerializerMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XPointerMessages"); - ImageSingletons.lookup(RuntimeResourceSupport.class).addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xalan.internal.res.XSLTInfo"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.utils.SerializerMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.Encodings"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.HTMLEntities"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xml.internal.serializer.XMLEntities"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.xpath.regex.message"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.DOMMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.DatatypeMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.JAXPValidationMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.SAXMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XIncludeMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLSchemaMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XMLSerializerMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xerces.internal.impl.msg.XPointerMessages"); + ResourcesRegistry.singleton().addResourceBundles(ConfigurationCondition.alwaysTrue(), "com.sun.org.apache.xalan.internal.res.XSLTInfo"); classInitializationSupport.setConfigurationSealed(true); } diff --git a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java index cd038d4e0b3b..520fc421f15f 100644 --- a/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java +++ b/substratevm/src/com.oracle.svm.truffle/src/com/oracle/svm/truffle/TruffleBaseFeature.java @@ -517,7 +517,7 @@ public void duringSetup(DuringSetupAccess access) { } if (needsAllEncodings) { - ImageSingletons.lookup(RuntimeResourceSupport.class).addResources(ConfigurationCondition.alwaysTrue(), "org/graalvm/shadowed/org/jcodings/tables/.*bin$"); + RuntimeResourceSupport.singleton().addResources(ConfigurationCondition.alwaysTrue(), "org/graalvm/shadowed/org/jcodings/tables/.*bin$"); } }