Open wyhasany opened 1 day ago
This is similar to https://github.com/spring-projects/spring-boot/issues/35663, although that issue was using @ServiceConnection
on a field in a test class whereas this issue's using @ServiceConnection
on a @Bean
method. I wonder if that difference may be where the problem lies with the fix for #35663 possibly going too far and adversely affecting the @Bean
case as well as fixing the field case.
@wilkinsona it works with following configuration:
@SpringBootTest
@Testcontainers
class DemoApplicationTests {
@Container
@ServiceConnection
static MongoDBContainer mongoDbContainer = new MongoDBContainer(DockerImageName.parse("mongo:latest"));
@Test
void contextLoads() {
}
}
That's good to know, @wyhasany. Thank you. We'll see what we can do for the @Bean
approach.
@wilkinsona I've been trying to use this way:
@SpringBootTest
@ImportTestcontainers
class DemoApplicationTests {
@ServiceConnection
private static final MongoDBContainer mongoDbContainer =
new MongoDBContainer(DockerImageName.parse("mongo:latest"));
@Test
void contextLoads() {
}
}
it also fails due to the following:
Exception in thread "main" org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [com.example.demo.DemoApplicationTests]
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:286)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179)
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:244)
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 [com.example.demo.DemoApplicationTests] for AOT
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:323)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [com.example.demo.DemoApplicationTests] for AOT
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:277)
... 9 more
Caused by: java.lang.IllegalStateException: Error processing bean with name 'importTestContainer.com.example.demo.DemoApplicationTests.mongoDbContainer': instance supplier is not supported
at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.getTarget(DefaultBeanRegistrationCodeFragments.java:83)
Caused by: java.lang.IllegalStateException: Error processing bean with name 'importTestContainer.com.example.demo.DemoApplicationTests.mongoDbContainer': instance supplier is not supported
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:85)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$generateRegisterBeanDefinitionsMethod$2(BeanRegistrationsAotContribution.java:90)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
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:319)
... 10 more
That's interesting. Thanks, @nosan. That looks like another variant of #35663 as AOT processing is occurring but it's trying to produce something that isn't valid. We might need a separate issue for that, but let's just stick with this one for now until we have a complete understanding of what works, what doesn't work, and why.
I've opened https://github.com/spring-projects/spring-boot/issues/42875 for the problem with @ImportTestcontainers
.
Undoing the fix for #35663 results in the following failure during AOT processing:
Exception in thread "main" org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [com.example.demo.DemoApplicationTests]
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:286)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:179)
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:244)
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:81)
at org.springframework.boot.test.context.SpringBootTestAotProcessor.main(SpringBootTestAotProcessor.java:63)
Caused by: org.springframework.test.context.aot.TestContextAotException: Failed to process test class [com.example.demo.DemoApplicationTests] for AOT
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:323)
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$5(TestContextAotGenerator.java:277)
... 9 more
Caused by: java.lang.IllegalStateException: Error processing bean with name 'mongoContainerConnectionDetailsForMongoDbContainer': instance supplier is not supported
at org.springframework.beans.factory.aot.DefaultBeanRegistrationCodeFragments.getTarget(DefaultBeanRegistrationCodeFragments.java:83)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGenerator.generateBeanDefinitionMethod(BeanDefinitionMethodGenerator.java:85)
at org.springframework.beans.factory.aot.BeanRegistrationsAotContribution.lambda$generateRegisterBeanDefinitionsMethod$2(BeanRegistrationsAotContribution.java:90)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
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:319)
... 10 more
This is caused by ConnectionDetailsRegistrar
defining a bean that uses an instance supplier:
Unlike #35663, where there is a test context customizer that will register the beans when the tests are being run, skipping these beans results in them not being defined at all. It looks like we need to find a way to register them during AOT processing without using an instance supplier.
Spring Boot application fails to run the
nativeTest
task with Testcontainers.I generated a simple project using start.spring.io:
On the first run, it fails due to a reflection issue:
I solved this issue by adding a
reflect.json
file insrc/test/resources/META-INF/native-image/
with the following content::However, I'm confused because Testcontainers seems to be supported by GraalVM as indicated here: https://www.graalvm.org/native-image/libraries-and-frameworks/
With that configuration, I encountered another issue that I'm unsure how to resolve:
It looks like the task
aotTestClasses
doesn't add anyMongoConnectionDetails
to the application context.Here is the zipped project for reference: demo.zip
Environment Details
I'm using the following version of GraalVM: