diff --git a/framework-docs/modules/ROOT/pages/appendix.adoc b/framework-docs/modules/ROOT/pages/appendix.adoc index c3074a81a6..c6c7d9d898 100644 --- a/framework-docs/modules/ROOT/pages/appendix.adoc +++ b/framework-docs/modules/ROOT/pages/appendix.adoc @@ -55,6 +55,11 @@ for details. {api-spring-framework}++/objenesis/SpringObjenesis.html#IGNORE_OBJENESIS_PROPERTY_NAME++[`SpringObjenesis`] for details. +| `spring.test.aot.processing.failOnError` +| A boolean flag that controls whether errors encountered during AOT processing in the +_Spring TestContext Framework_ should result in an exception that fails the overall process. +See xref:testing/testcontext-framework/aot.adoc[Ahead of Time Support for Tests]. + | `spring.test.constructor.autowire.mode` | The default _test constructor autowire mode_ to use if `@TestConstructor` is not present on a test class. See xref:testing/annotations/integration-junit-jupiter.adoc#integration-testing-annotations-testconstructor[Changing the default test constructor autowire mode]. diff --git a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc index 5f9c7c97f6..b6dcc2b247 100644 --- a/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc +++ b/framework-docs/modules/ROOT/pages/testing/testcontext-framework/aot.adoc @@ -19,7 +19,22 @@ following features. use an AOT-optimized `ApplicationContext` that participates transparently with the xref:testing/testcontext-framework/ctx-management/caching.adoc[context cache]. -[WARNING] +[TIP] +==== +By default, if an error is encountered during build-time AOT processing, an exception +will be thrown, and the overall process will fail immediately. + +If you would prefer that build-time AOT processing continue after errors are encountered, +you can disable the `failOnError` mode which results in errors being logged at `WARN` +level or with greater detail at `DEBUG` level. + +The `failOnError` mode can be disabled from the command line or a build script by setting +a JVM system property named `spring.test.aot.processing.failOnError` to `false`. As an +alternative, you can set the same property via the +xref:appendix.adoc#appendix-spring-properties[`SpringProperties`] mechanism. +==== + +[NOTE] ==== The `@ContextHierarchy` annotation is currently not supported in AOT mode. ==== 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 4cce32599b..b1fabb79f3 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 @@ -43,6 +43,7 @@ import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.annotation.ImportRuntimeHints; import org.springframework.context.aot.ApplicationContextAotGenerator; import org.springframework.context.support.GenericApplicationContext; +import org.springframework.core.SpringProperties; import org.springframework.core.annotation.MergedAnnotation; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; @@ -56,6 +57,7 @@ import org.springframework.test.context.TestContextBootstrapper; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import static org.springframework.aot.hint.MemberCategory.INVOKE_DECLARED_CONSTRUCTORS; import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_METHODS; @@ -70,8 +72,26 @@ import static org.springframework.aot.hint.MemberCategory.INVOKE_PUBLIC_METHODS; */ public class TestContextAotGenerator { + /** + * JVM system property used to set the {@code failOnError} flag: {@value}. + *
The {@code failOnError} flag controls whether errors encountered during + * AOT processing in the Spring TestContext Framework should result + * in an exception that fails the overall process. + *
Defaults to {@code true}. + *
Supported values include {@code true} or {@code false}, ignoring case. + * For example, the default may be changed to {@code false} by supplying + * the following JVM system property via the command line. + *
-Dspring.test.aot.processing.failOnError=false+ *
May alternatively be configured via the
+ * {@link org.springframework.core.SpringProperties SpringProperties}
+ * mechanism.
+ * @since 6.1
+ */
+ public static final String FAIL_ON_ERROR_PROPERTY_NAME = "spring.test.aot.processing.failOnError";
+
private static final Log logger = LogFactory.getLog(TestContextAotGenerator.class);
+
private final ApplicationContextAotGenerator aotGenerator = new ApplicationContextAotGenerator();
private final AotServices This constructor looks up the value of the {@code failOnError} flag via
+ * the {@value #FAIL_ON_ERROR_PROPERTY_NAME} property, defaulting to
+ * {@code true} if the property is not set.
* @param generatedFiles the {@code GeneratedFiles} to use
* @param runtimeHints the {@code RuntimeHints} to use
+ * @see #TestContextAotGenerator(GeneratedFiles, RuntimeHints, boolean)
*/
public TestContextAotGenerator(GeneratedFiles generatedFiles, RuntimeHints runtimeHints) {
- this(generatedFiles, runtimeHints, false);
+ this(generatedFiles, runtimeHints, getFailOnErrorFlag());
}
/**
@@ -114,9 +139,9 @@ public class TestContextAotGenerator {
* @param runtimeHints the {@code RuntimeHints} to use
* @param failOnError {@code true} if errors encountered during AOT processing
* should result in an exception that fails the overall process
- * @since 6.0.12
+ * @since 6.1
*/
- TestContextAotGenerator(GeneratedFiles generatedFiles, RuntimeHints runtimeHints, boolean failOnError) {
+ public TestContextAotGenerator(GeneratedFiles generatedFiles, RuntimeHints runtimeHints, boolean failOnError) {
this.testRuntimeHintsRegistrars = AotServices.factories().load(TestRuntimeHintsRegistrar.class);
this.generatedFiles = generatedFiles;
this.runtimeHints = runtimeHints;
@@ -368,4 +393,12 @@ public class TestContextAotGenerator {
this.runtimeHints.reflection().registerType(type, INVOKE_DECLARED_CONSTRUCTORS);
}
+ private static boolean getFailOnErrorFlag() {
+ String failOnError = SpringProperties.getProperty(FAIL_ON_ERROR_PROPERTY_NAME);
+ if (StringUtils.hasText(failOnError)) {
+ return Boolean.parseBoolean(failOnError.trim());
+ }
+ return true;
+ }
+
}
diff --git a/spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java b/spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java
index c7b749fc9a..18d87c1d7e 100644
--- a/spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java
+++ b/spring-test/src/test/java/org/springframework/test/context/aot/AotIntegrationTests.java
@@ -87,7 +87,7 @@ class AotIntegrationTests extends AbstractAotTests {
// AOT BUILD-TIME: PROCESSING
InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles();
- TestContextAotGenerator generator = new TestContextAotGenerator(generatedFiles, new RuntimeHints(), true);
+ TestContextAotGenerator generator = new TestContextAotGenerator(generatedFiles, new RuntimeHints());
generator.processAheadOfTime(testClasses);
List