From 920fbb34c8332ddfb250933e5e3d456e6ff8aab2 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sat, 3 Sep 2022 17:25:46 +0200 Subject: [PATCH] Register runtime hints for @ContextConfiguration#locations This commit introduces automatic registration of runtime hints for classpath resources configured via the `locations` attribute in @ContextConfiguration. Closes gh-29021 --- .../test/context/aot/TestContextAotGenerator.java | 13 +++++++++++++ .../context/aot/TestContextAotGeneratorTests.java | 14 +++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java b/spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java index 244d20a2d69..ecd72daa005 100644 --- a/spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java +++ b/spring-test/src/main/java/org/springframework/test/context/aot/TestContextAotGenerator.java @@ -16,6 +16,7 @@ package org.springframework.test.context.aot; +import java.util.Arrays; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; @@ -47,6 +48,8 @@ import org.springframework.util.MultiValueMap; import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_CONSTRUCTORS; import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_METHODS; +import static org.springframework.util.ResourceUtils.CLASSPATH_URL_PREFIX; + /** * {@code TestContextAotGenerator} generates AOT artifacts for integration tests * that depend on support from the Spring TestContext Framework. @@ -242,6 +245,16 @@ public class TestContextAotGenerator { // @ContextConfiguration(initializers = ...) mergedConfig.getContextInitializerClasses().forEach(this::registerDeclaredConstructors); + + // @ContextConfiguration(locations = ...) + registerHintsForClasspathResources(mergedConfig.getLocations()); + } + + private void registerHintsForClasspathResources(String... locations) { + Arrays.stream(locations) + .filter(location -> location.startsWith(CLASSPATH_URL_PREFIX)) + .map(location -> location.substring(CLASSPATH_URL_PREFIX.length())) + .forEach(this.runtimeHints.resources()::registerPattern); } private void registerDeclaredConstructors(Class type) { diff --git a/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java b/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java index a2eb7c1ef71..9ecac208e5e 100644 --- a/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/aot/TestContextAotGeneratorTests.java @@ -59,6 +59,7 @@ import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_METHOD import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS; import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_METHODS; import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.reflection; +import static org.springframework.aot.hint.predicate.RuntimeHintsPredicates.resource; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -85,6 +86,7 @@ class TestContextAotGeneratorTests extends AbstractAotTests { BasicSpringJupiterTests.NestedTests.class, BasicSpringTestNGTests.class, BasicSpringVintageTests.class, + XmlSpringJupiterTests.class, WebSpringJupiterTests.class); InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles(); @@ -165,6 +167,10 @@ class TestContextAotGeneratorTests extends AbstractAotTests { // @ContextConfiguration(loader=...) org.springframework.test.context.support.AnnotationConfigContextLoader.class ).forEach(type -> assertReflectionRegistered(runtimeHints, type, INVOKE_DECLARED_CONSTRUCTORS)); + + // @ContextConfiguration(locations=...) + assertThat(resource().forResource("/org/springframework/test/context/aot/samples/xml/test-config.xml")) + .accepts(runtimeHints); } private static void assertReflectionRegistered(RuntimeHints runtimeHints, String type, MemberCategory memberCategory) { @@ -320,7 +326,13 @@ class TestContextAotGeneratorTests extends AbstractAotTests { "org/springframework/test/context/aot/samples/web/WebTestConfiguration__TestContext005_BeanDefinitions.java", "org/springframework/web/reactive/config/DelegatingWebFluxConfiguration__TestContext005_Autowiring.java", "org/springframework/web/reactive/config/DelegatingWebFluxConfiguration__TestContext005_BeanDefinitions.java", - "org/springframework/web/reactive/config/WebFluxConfigurationSupport__TestContext005_BeanDefinitions.java" + "org/springframework/web/reactive/config/WebFluxConfigurationSupport__TestContext005_BeanDefinitions.java", + // XmlSpringJupiterTests + "org/springframework/context/event/DefaultEventListenerFactory__TestContext006_BeanDefinitions.java", + "org/springframework/context/event/EventListenerMethodProcessor__TestContext006_BeanDefinitions.java", + "org/springframework/test/context/aot/samples/common/DefaultMessageService__TestContext006_BeanDefinitions.java", + "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext006_ApplicationContextInitializer.java", + "org/springframework/test/context/aot/samples/xml/XmlSpringJupiterTests__TestContext006_BeanFactoryRegistrations.java" }; }