AOT Repositories: OwnerRepository.json already exists
Closed this issue · 8 comments
I've upgraded Spring Petclinic to use Spring Boot 4.0.0-M2. When building with Maven ./mvnw verify all works. When building with Gradle (./gradlew build), processTestAot fails with:
Exception in thread "main" org.springframework.test.context.aot.TestContextAotException: Failed to generate AOT artifacts for test classes [org.springframework.samples.petclinic.PostgresIntegrationTests]
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$3(TestContextAotGenerator.java:286)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721)
at org.springframework.util.MultiValueMapAdapter.forEach(MultiValueMapAdapter.java:174)
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:84)
at org.springframework.boot.test.context.SpringBootTestAotProcessor.main(SpringBootTestAotProcessor.java:63)
Caused by: java.lang.IllegalStateException: /home/mhalbritter/Projects/mhalbritter/spring-petclinic/build/generated/aotTestResources/org/springframework/samples/petclinic/owner/OwnerRepository.json already exists
at org.springframework.aot.generate.GeneratedFiles$FileHandler.create(GeneratedFiles.java:279)
at org.springframework.aot.generate.GeneratedFiles.lambda$addFile$1(GeneratedFiles.java:170)
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60)
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:49)
at org.springframework.aot.generate.FileSystemGeneratedFiles.handleFile(FileSystemGeneratedFiles.java:90)
at org.springframework.aot.generate.GeneratedFiles.addFile(GeneratedFiles.java:170)
at org.springframework.aot.generate.GeneratedFiles.addFile(GeneratedFiles.java:155)
at org.springframework.aot.generate.GeneratedFiles.addResourceFile(GeneratedFiles.java:109)
at org.springframework.aot.generate.GeneratedFiles.addResourceFile(GeneratedFiles.java:98)
at org.springframework.data.repository.aot.generate.RepositoryContributor.lambda$contribute$0(RepositoryContributor.java:135)
at org.springframework.aot.generate.GeneratedClass.getBuilder(GeneratedClass.java:153)
at org.springframework.aot.generate.GeneratedClass.apply(GeneratedClass.java:143)
at org.springframework.aot.generate.GeneratedClass.generateJavaFile(GeneratedClass.java:138)
at org.springframework.aot.generate.GeneratedClasses.writeTo(GeneratedClasses.java:199)
at org.springframework.aot.generate.DefaultGenerationContext.writeGeneratedContent(DefaultGenerationContext.java:136)
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$3(TestContextAotGenerator.java:281)
... 9 more
I couldn't spot any bugs in the Gradle setup, so I think this is a bug in Spring Data. Maybe related to #3339?
You can find the Spring Petclinic with Boot 4.0.0-M2 in this branch.
Indeed a variant of the mentioned ticket. Thanks for the report, we will have a look.
thanks @mhalbritter - I'm curious what's the difference between the maven and gradle build since both are running the same aot processing, right?
Nevertheless it might make sense to also write test context specific json metadata for repo methods
I'm not sure when exactly the test processing for maven is run. Maybe only when executing mvn native:test -P native?
But you can trigger it manually with ./mvnw org.springframework.boot:spring-boot-maven-plugin:process-test-aot and see the same error as with Gradle.
Ah, I'm using gradle for such a long time that i've forgotten about the nativeTest profile. This is how you can see the failure on Maven side:
./mvnw verify -PnativeTest
With Gradle, the AOT test processing is configured automatically, because the Spring Boot Gradle plugin reacts to the application of the native build tools plugin.
thanks for confirming same error occurs with maven. it's a bit tricky to extract/map the generated type name to the repo pattern.
Do you know of a way to safely add resources files with generated index names? Right now there's only a couple of addResource methods available on GeneratedFiles but nothing like getOrAddForFeatureComponent that would provide a sequential file name for additional generation runs for test contexts.
No sorry, i don't know very much about GeneratedFiles.
So we could write the json file like this, preserving the source repository interface simpleName and the potentially generated sequence created during testing.
./main/sources/org/springframework/samples/petclinic/owner/OwnerRepositoryImpl__AotRepository.java
./main/resources/org/springframework/samples/petclinic/owner/OwnerRepository.json
./test/sources/org/springframework/samples/petclinic/owner/OwnerRepositoryImpl__TestContext001_AotRepository.java
./test/resources/org/springframework/samples/petclinic/owner/OwnerRepository__TestContext001.json
Another options would be to catch the file writing fault and back off - which would arguably make senes since the json is more for tooling and doesn't contribute to the test execution in any way - or request changes to generated resource file handing.
So we, decided to back off if the file already exists since there's next to no benefit for having individual ones per test context.
@mhalbritter if you want to give snapshots of spring-data-commons:4.0.x-GH-3354-SNAPSHOT a try you'll also have to use snapshots for data-jpa.