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 25e27f7b2f..dd52fe4025 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 @@ -205,6 +205,7 @@ public class TestContextAotGenerator { MultiValueMap> initializerClassMappings = processAheadOfTime(mergedConfigMappings); generateAotTestContextInitializerMappings(initializerClassMappings); generateAotTestAttributeMappings(); + registerSkippedExceptionTypes(); } finally { resetAotFactories(); @@ -422,6 +423,20 @@ public class TestContextAotGenerator { this.runtimeHints.reflection().registerType(type, INVOKE_DECLARED_CONSTRUCTORS); } + /** + * Register hints for skipped exception types loaded via reflection in + * {@link org.springframework.test.context.TestContextManager}. + * @since 6.1.2 + */ + private void registerSkippedExceptionTypes() { + Stream.of( + "org.opentest4j.TestAbortedException", + "org.junit.AssumptionViolatedException", + "org.testng.SkipException") + .map(TypeReference::of) + .forEach(this.runtimeHints.reflection()::registerType); + } + private static boolean getFailOnErrorFlag() { String failOnError = SpringProperties.getProperty(FAIL_ON_ERROR_PROPERTY_NAME); if (StringUtils.hasText(failOnError)) { 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 ecdc96d729..26e9651f72 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 @@ -158,6 +158,12 @@ class TestContextAotGeneratorTests extends AbstractAotTests { assertReflectionRegistered(runtimeHints, AotTestContextInitializersCodeGenerator.GENERATED_MAPPINGS_CLASS_NAME, INVOKE_PUBLIC_METHODS); assertReflectionRegistered(runtimeHints, AotTestAttributesCodeGenerator.GENERATED_ATTRIBUTES_CLASS_NAME, INVOKE_PUBLIC_METHODS); + Stream.of( + "org.opentest4j.TestAbortedException", + "org.junit.AssumptionViolatedException", + "org.testng.SkipException" + ).forEach(type -> assertReflectionRegistered(runtimeHints, type)); + Stream.of( org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.class, org.springframework.test.context.support.DefaultBootstrapContext.class @@ -239,6 +245,12 @@ class TestContextAotGeneratorTests extends AbstractAotTests { .accepts(runtimeHints); } + private static void assertReflectionRegistered(RuntimeHints runtimeHints, String type) { + assertThat(reflection().onType(TypeReference.of(type))) + .as("Reflection hint for %s", type) + .accepts(runtimeHints); + } + private static void assertReflectionRegistered(RuntimeHints runtimeHints, String type, MemberCategory memberCategory) { assertThat(reflection().onType(TypeReference.of(type)).withMemberCategory(memberCategory)) .as("Reflection hint for %s with category %s", type, memberCategory)