spring-content icon indicating copy to clipboard operation
spring-content copied to clipboard

Maven build error with Graal VM on Spring Content

Open AkshathSai opened this issue 2 years ago • 5 comments

Hi There,

When attempting to build my project using Graal VM, I encountered an error. I'm not sure if Spring Content supports Graal VM, but I'm raising this issue in case it's a bug or if support could be added.

Expected Result: Successful build using either of the following commands:

mvn -Pnative native:compile

or

 mvn clean package -Pnative

Actual Result: Maven build fails with the following error (stack trace below).

2023-10-25T21:17:58.174+05:30  INFO 2035 --- [           main] rocessor$ProxyRegisteringAotContribution : Created proxy type class org.springdoc.webmvc.ui.SwaggerWelcomeWebMvc$$SpringCGLIB$$0 for class org.springdoc.webmvc.ui.SwaggerWelcomeWebMvc
2023-10-25T21:17:58.181+05:30  INFO 2035 --- [           main] rocessor$ProxyRegisteringAotContribution : Created proxy type class org.springdoc.webmvc.ui.SwaggerConfigResource$$SpringCGLIB$$0 for class org.springdoc.webmvc.ui.SwaggerConfigResource
2023-10-25T21:17:58.283+05:30  INFO 2035 --- [           main] o.springframework.hateoas.aot.AotUtils   : Registering Spring HATEOAS types in org.springframework.hateoas for reflection.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.308 s
[INFO] Finished at: 2023-10-25T21:17:59+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.1.5:process-aot (process-aot) on project CinemaPass: Unable to compile generated source
[ERROR] incompatible types: bad return type in lambda expression
[ERROR]     internal.org.springframework.content.commons.config.StoreFragmentsFactoryBean cannot be converted to internal.org.springframework.content.commons.config.StoreFragments /Users/akshathsaipittala/Git/CinemaPass/target/spring-aot/main/sources/internal/org/springframework/content/commons/config/StoreFragments__BeanDefinitions.java 19:54
[ERROR] incompatible types: bad return type in lambda expression
[ERROR]     internal.org.springframework.content.commons.config.StoreFragmentsFactoryBean cannot be converted to internal.org.springframework.content.commons.config.StoreFragments /Users/akshathsaipittala/Git/CinemaPass/target/spring-aot/main/sources/internal/org/springframework/content/commons/config/StoreFragments__BeanDefinitions.java 58:54
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
dev@Devs-MacBook-Pro CinemaPass % 

Steps to Reproduce:

  1. Use the following tech stack versions:
    • Spring Boot: 3.1.5
    • Spring Content Version: 3.0.6 (Using both spring-content-fs-boot-starter & spring-content-rest-boot-starter)
    • Maven: 3.9.2
    • Graal VM Community Edition: 21
  2. Run the following command: mvn -Pnative native:compile or mvn clean package -Pnative

AkshathSai avatar Oct 25 '23 16:10 AkshathSai

Hi @AkshathSai, I tried to repro this using one of the getting started guides and I am unable to. That seems to produce a native image - although I am not sure it works.

Any chance you have a project that shows the problem?

paulcwarren avatar Nov 08 '23 05:11 paulcwarren

Hi Paul, thx for considering this issue. You may use this attached stripped down sample replica project, the command used for native image compilation "mvn -Pnative native:compile"

tunes.zip

AkshathSai avatar Nov 08 '23 18:11 AkshathSai

Thanks. That's helpful. I took a look at this and the compilation error is spring-aot generated code which is obviously to do with producing the native image. Probably not adding much value by stating that alone.

As I understand it native images operate with a "closed world" principle where, in Spring terms, all beans need to be known ahead of time during compilation.

Spring in general and by implication Spring Data and Spring Content rely heavily on runtime reflection to generate proxy classes that act as the implementation for your musicRepo and musicStore (amoungst other things).

Digging into Spring Data I can see that they have added a bunch AotProcessor classes like this one for example. I am 99% sure are there to help the Spring Aot Processor generate the right BeanDefinition classes for an application.

Spring Content does not have any of these yet and therefore we can probably be reasonably confident in sayng that Spring Content does not yet support Spring Native.

At this point I don't have the first clue what those Spring Data Aot Processor classes are doing. I can guess but that about it. So I'll need to really dig into those and try and understand them as best I can. Then see if I can replicate that behavior in Spring Content. But that might take a while I am afraid.

paulcwarren avatar Nov 09 '23 05:11 paulcwarren

Thank you for the detailed explanation. It's clear that the issue I'm facing is due to the absence of AotProcessor classes in Spring Content, which are essential for Spring AOT to generate the right BeanDefinition classes for an application. Your insight that Spring Content doesn't support Spring Native yet is enlightening.

I understand the "closed world" principle of native images. Indeed, Spring, and by extension, Spring Data and Spring Content, heavily rely on runtime reflection to generate proxy classes that act as the implementation for repositories and stores. The lack of support for this in Spring Content when using Spring Native is the root of the problem.

I appreciate your willingness to dive deeper into the Spring Data AotProcessor classes despite your unfamiliarity with them. Your commitment to understand these classes and try to replicate their behavior in Spring Content is commendable.

I understand that this process might take some time. I thank you in advance for your efforts and look forward to updates on this issue. In the meantime, I will continue to play around in my project and keep track of updates on Spring Native's support for Spring Content.

Once again, thank you for your assistance and the time you've dedicated for considering this issue.

AkshathSai avatar Nov 10 '23 12:11 AkshathSai