I've recently upgraded my app to Spring Boot 3.2 and Java 21. We use Spring Data JDBC and have tests that mock our repositories with @MockBean
. After upgrading, when I run ./gradlew build
I get this failure. The tests are all failing during the AOT code generation phase with this error.
Exception in thread "main" org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [<list of our classes>]
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:285)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986)
at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179)
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:243)
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:205)
at org.springframework.test.context.aot.TestAotProcessor.performAotProcessing(TestAotProcessor.java:91)
at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:72)
at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:39)
at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
at org.springframework.boot.test.context.SpringBootTestAotProcessor.main(SpringBootTestAotProcessor.java:63)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [<failing test class>] for AOT
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:322)
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:276)
... 9 more
Caused by: java.lang.IllegalArgumentException: Failed to generate code for '[[MockDefinition@5b5f61cc name = '', typeToMock = <Spring Data JDBC repository being mocked>, extraInterfaces = set[[empty]], answer = RETURNS_DEFAULTS, serializable = false, reset = AFTER]]' with type java.util.LinkedHashSet<?>
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:105)
at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateValue(BeanDefinitionPropertiesCodeGenerator.java:257)
at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.lambda$addConstructorArgumentValues$3(BeanDefinitionPropertiesCodeGenerator.java:179)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986)
at java.base/java.util.Collections$UnmodifiableMap.forEach(Collections.java:1707)
at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.addConstructorArgumentValues(BeanDefinitionPropertiesCodeGenerator.java:176)
at org.springframework.beans.factory.aot.BeanDefinitionPropertiesCodeGenerator.generateCode(BeanDefinitionPropertiesCodeGenerator.java:126)
at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.generateSetBeanDefinitionPropertiesCode(DefaultBeanRegistrationCodeFragments.java:176)
at org.springframework.beans.factory.aot.BeanRegistrationCodeGenerator.generateCode(BeanRegistrationCodeGenerator.java:81)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.lambda$generateBeanDefinitionMethod$3(BeanDefinitionMethodGenerator.java:176)
at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:169)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:89)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$generateRegisterBeanDefinitionsMethod$2(BeanRegistrationsAotContribution.java:90)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:986)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.generateRegisterBeanDefinitionsMethod(BeanRegistrationsAotContribution.java:88)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$applyTo$1(BeanRegistrationsAotContribution.java:73)
at org.springframework.aot.generate.GeneratedMethod.<init>(GeneratedMethod.java:54)
at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:112)
at org.springframework.aot.generate.GeneratedMethods.add(GeneratedMethods.java:89)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.applyTo(BeanRegistrationsAotContribution.java:72)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.applyTo(BeanFactoryInitializationAotContributions.java:78)
at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:318)
... 10 more
Caused by: java.lang.IllegalArgumentException: Failed to generate code for '[MockDefinition@5b5f61cc name = '', typeToMock = <Spring Data JDBC repository being mocked>, extraInterfaces = set[[empty]], answer = RETURNS_DEFAULTS, serializable = false, reset = AFTER]' with type ?
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCodeForElement(BeanDefinitionPropertyValueCodeGenerator.java:114)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$CollectionDelegate.generateCollectionOf(BeanDefinitionPropertyValueCodeGenerator.java:351)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$SetDelegate.generateCollectionCode(BeanDefinitionPropertyValueCodeGenerator.java:450)
> Task :processTestAot FAILED
10 actionable tasks: 1 executed, 9 up-to-date
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$SetDelegate.generateCollectionCode(BeanDefinitionPropertyValueCodeGenerator.java:440)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator$CollectionDelegate.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:334)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:132)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:102)
... 37 more
Caused by: java.lang.IllegalArgumentException: Code generation does not support ?
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCode(BeanDefinitionPropertyValueCodeGenerator.java:137)
at org.springframework.beans.factory.aot.BeanDefinitionPropertyValueCodeGenerator.generateCodeForElement(BeanDefinitionPropertyValueCodeGenerator.java:111)
... 43 more
It seems to be triggered by the @MockBean
entry. If I comment out that type, then I can get a clean build.
I don't know where that ?
is coming from as none of my repository types are using that. They are all pretty standard types, like...
public interface FooRepository extends ListCrudRepository<Foo, UUID>, PagingAndSortingRepository<Foo, UUID> {
}
Looking for ways to fix this, or at least work around the issue. Thanks
I get the same exception for my test, but only when run with Gradle, not Maven (no idea why that matters though..).
The issue for me was caused by the fact that I had tests with
@DisabledInAotMode
annotation and according to the documentation of that annotation:Once I added
@DisabledInAotMode
to the test class that originally threw the exception it resolved the issue and all tests pass.UPDATE: Actually it's even simpler - every test class that contains
@MockBean
needs@DisabledInAotMode
annotation (regardless of what's happening in any other test classes), in a Gradle project and if you're using Spring Core 6.1.0+ (Spring Boot 3.2+).