Hello
I'am using SB 3.0.2. I'm trying to pass the tests with native compilation with mvn -PnativeTest clean install and I get the following error
2023-02-22T09:14:51.320+01:00 WARN 28134 --- [ main] o.s.t.c.aot.TestContextAotGenerator : Failed to generate AOT artifacts for test classes [com.example.testactuatornative.Test2ITTest]
java.lang.IllegalStateException: java.nio.file.FileAlreadyExistsException: /home/n129586/wks/test/test-actuator-native/target/spring-aot/test/sources/org/springframework/boot/actuate/autoconfigure/endpoint/web/CorsEndpointProperties__ManagementBeanDefinitions.java
at org.springframework.aot.generate.FileSystemGeneratedFiles.addFile(FileSystemGeneratedFiles.java:97) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.aot.generate.GeneratedFiles.addFile(GeneratedFiles.java:149) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.aot.generate.GeneratedFiles.addSourceFile(GeneratedFiles.java:70) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.aot.generate.GeneratedFiles.addSourceFile(GeneratedFiles.java:47) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.aot.generate.GeneratedClasses.writeTo(GeneratedClasses.java:198) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.aot.generate.DefaultGenerationContext.writeGeneratedContent(DefaultGenerationContext.java:127) ~[spring-core-6.0.4.jar:6.0.4]
at org.springframework.test.context.aot.TestContextAotGenerator.lambda$processAheadOfTime$4(TestContextAotGenerator.java:209) ~[spring-test-6.0.4.jar:6.0.4]
at java.base/java.util.Map.forEach(Map.java:713) ~[na:na]
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:197) ~[spring-test-6.0.4.jar:6.0.4]
at org.springframework.test.context.aot.TestContextAotGenerator.processAheadOfTime(TestContextAotGenerator.java:159) ~[spring-test-6.0.4.jar:6.0.4]
at org.springframework.test.context.aot.TestAotProcessor.performAotProcessing(TestAotProcessor.java:91) ~[spring-test-6.0.4.jar:6.0.4]
at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:72) ~[spring-test-6.0.4.jar:6.0.4]
at org.springframework.test.context.aot.TestAotProcessor.doProcess(TestAotProcessor.java:39) ~[spring-test-6.0.4.jar:6.0.4]
at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82) ~[spring-context-6.0.4.jar:6.0.4]
at org.springframework.boot.test.context.SpringBootTestAotProcessor.main(SpringBootTestAotProcessor.java:57) ~[spring-boot-test-3.0.2.jar:3.0.2]
Caused by: java.nio.file.FileAlreadyExistsException: /home/n129586/wks/test/test-actuator-native/target/spring-aot/test/sources/org/springframework/boot/actuate/autoconfigure/endpoint/web/CorsEndpointProperties__ManagementBeanDefinitions.java
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:94) ~[na:na]
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[na:na]
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[na:na]
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218) ~[na:na]
at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:484) ~[na:na]
at java.base/java.nio.file.Files.newOutputStream(Files.java:228) ~[na:na]
at java.base/java.nio.file.Files.copy(Files.java:3160) ~[na:na]
at org.springframework.aot.generate.FileSystemGeneratedFiles.addFile(FileSystemGeneratedFiles.java:93) ~[spring-core-6.0.4.jar:6.0.4]
... 14 common frames omitted
I think this happens if I have two tests of type @SpringBootTest with property management.server.port=0.
I have tried to create a minimal example: https://github.com/ruben-garciapariente/test-actuator-native
Thanks & regards
Comment From: mhalbritter
Thanks for the report, there's something wrong here. It seems that if two management contexts exists, it leads to this error.
If i for example remove the value1=value1 and value2=value2 properties from your tests, the context will be cached and the error is gone.
Comment From: Jul13nT
I stumbled across the same error. Here is my repo with the error: https://github.com/Jul13nT/native-test-actuator
Run ./gradlew test and I get the exact same error.
One difference is that the management.server.port is set globally in application.properties. Then I have one test with @SpringBootTest and one with @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT).
Because of this, none of our tests of all our services are running and it prevents us of using GraalVM. Is there a possible workaround?
Comment From: robert-fennell-bk
I stumbled across the same error. Here is my repo with the error: https://github.com/Jul13nT/native-test-actuator
Run
./gradlew testand I get the exact same error.One difference is that the
management.server.portis set globally inapplication.properties. Then I have one test with@SpringBootTestand one with@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT).Because of this, none of our tests of all our services are running and it prevents us of using GraalVM. Is there a possible workaround?
I also ran into this bug in the same way.
To work around it, I moved all management.* properties into a properties file named application-actuator.properties, and then I'm compiling and running the application with the actuator profile enabled, but during testing I don't activate this profile.
If you do want to create integration tests to verify the actuator, it's still possible by creating a test classes annotated with @ActiveProfiles("actuator"), but you have to be careful not to create multiple test classes with this profile that might also try to change the test context in a different way.
Comment From: snicoll
I believe this is a duplicate of https://github.com/spring-projects/spring-framework/issues/28974.
Comment From: sbrannen
- see also https://github.com/spring-projects/spring-framework/issues/30861
Comment From: snicoll
Oh well, a duplicate of https://github.com/spring-projects/spring-framework/issues/30861 then.
Comment From: sbrannen
The error can also be reproduced by running the tests in AOT mode on the JVM as follows.
./mvnw clean test spring-boot:process-test-aot && ./mvnw -Dspring.aot.enabled=true test
More importantly...
This issue has been fixed for the upcoming Spring Framework 6.0.12 release (see https://github.com/spring-projects/spring-framework/issues/30861).
To verify things work as expected, I updated pom.xml in the linked project as follows.
<properties>
<java.version>17</java.version>
<spring-framework.version>6.0.12-SNAPSHOT</spring-framework.version>
</properties>
<repositories>
<repository>
<id>repository.spring.snapshot</id>
<name>Spring Snapshot Repository</name>
<url>https://repo.spring.io/snapshot</url>
</repository>
</repositories>
With that, the tests now pass in AOT mode on the JVM and within a native image.
@ruben-garciapariente, @Jul13nT, and @robert-fennell-bk: feel free to give it a try with 6.0.12-SNAPSHOT, and let us know if you run into any issues.
Comment From: meletis
I also ran into this bug in the same way.
To work around it, I moved all
management.*properties into a properties file namedapplication-actuator.properties, and then I'm compiling and running the application with theactuatorprofile enabled, but during testing I don't activate this profile.If you do want to create integration tests to verify the actuator, it's still possible by creating a test classes annotated with
@ActiveProfiles("actuator"), but you have to be careful not to create multiple test classes with this profile that might also try to change the test context in a different way.
@robert-fennell-bk , I also ran into the same issue and I followed your suggestion, but with no luck. I even deleted all my managenent.* and server.* properties as another test but that failed too. In my last test, which also failed, I also removed the org.springframework.boot:spring-boot-starter-actuator dependency completely.
Is there any chance that you can remember what kind of detective work you did back then in order to identify the root cause for your case? I believe I can follow the same steps as you did in order to find out what more/else is special about my app that is still suffering from this bug.
Thank you in advance!
Comment From: wilkinsona
@meletis what version of Spring Boot are you using? If you have the problem discussed in this issue, it should be fixed in Spring Boot 3.0.11 and later and 3.1.4 and later through the upgrade to Spring Framework 6.0.12. If you're already using such a version of Spring Boot then you may have a different problem.
Comment From: meletis
@wilkinsona , thanks, but I'm using Spring Boot 3.2.0. Yes, everything was fine until recently, when I was on 3.1.5.
Comment From: wilkinsona
@meletis, that sounds like it may be a different problem. If you would like us to investigate, please open a new issue and provide a minimal sample that reproduces it.
Comment From: meletis
@wilkinsona , actually, I just realized that is very similar to https://github.com/spring-projects/spring-boot/issues/36997, which is also on 3.2.0.
I also just discovered a IntelliJ plugin that can automatically attach the debugger to Java processes spawned by Gradle processes, so I'm now able to debug the TestContextAotGenerator, so I should have a solution soon. I will keep you posted here.
Comment From: meletis
Okay, that was easy with the debugger.
I managed to reproduce the issue at my repo, using the develop branch: https://github.com/meletis/native-build-tools-bug-report/pull/1
There is one test class that is using an @Autowired instance of the service class and another test class that is using an @MockBean instance of the service class. The difference is what is causing the generation of two MergedContextConfiguration classes.