spring-projects / spring-projects/spring-framework

Refine Spring profile support with AOT/native

Open
#29,844 9 comments 12 reactions 1 assignee View on GitHub

@sdeleuze is already working on this.

Since Jan 18, 2023.

in: core theme: aot type: enhancement
Dominant language
Java
Stars
60.2k
Forks
38.8k
Avg merge
5d 2h
Merged PRs (30d)
27

Description

Developers of Spring applications on the JVM are typically accustomed to being able to do advanced configuration at runtime with mechanisms like Spring profiles. Ahead-Of-Time transformations and GraalVM native image by design require one to define at build time the various beans. What can and cannot change at runtime is usually not well understood.

This issue is an attempt to clarify the current state of affairs (could materialize as a documentation update in 6.0.x), discuss what could be improved, and what will likely not be supported. What is discussed here will likely require related Spring Boot issue(s) since changes are likely to be required on both Spring Framework and Spring Boot projects, but let's start the discussion here.

I have created this https://github.com/sdeleuze/demo-profile-aot repository to illustrate the behavior of a generated Spring Boot native executable. It is possible at runtime:

  • To enable the Spring Boot debug flag with demo-profile-aot --debug
  • To customize the log level with demo-profile-aot -Dlogging.level.org.springframework.beans.factory.support.DefaultListableBeanFactory=debug
  • To enable a profile that does not impact the beans created with demo-profile-aot -Dspring.profiles.active=local
  • You can also customize a configuration property value specifying directly the property value with demo-profile-aot -Dsample.message="Customized message from the command line"
    What you can't do is enabling at runtime a profile that involves changing the bean configuration (for example adding a new bean specific to a profile). See the repository above for more details.

While this limitation can be initially frustrating, I think it makes sense if we take a step back on what the purpose of AOT transformation is and the goal of native application to ship only what is necessary in the native executable. It is important to have in mind that it is recommended to create the native executable (from sources or from the Spring Boot executable JAR) as late as possible in the deployment process, as close as possible to the target server when it will be deployed, usually as a container. In that sense, the generated native executable is not the strict equivalent of the executable JAR: it is CPU architecture specific and has a predefined set of beans. Removing this limitation is technically possible but would involve a huge refactoring of how conditions are evaluated AOT and would probably end up with increased footprint, build time, and executable size since more code would be shipped. I tend to think our time is better spent on other topics.

That said, I am in favor of adding the capability for people to specify the profiles to use with AOT/Native at build time. Once supported on Spring Framework AOT engine, this could translate on Spring Boot side to adding the capability to specify, for example (the way it is specified would be decided by the Spring Boot team):

  • With Gradle: gradle nativeCompile -Dspring.profiles.active=prod
  • With Maven: mvn -Pnative native:compile -Dspring.profiles.active=prod

This would allow developers to deal for example with different databases (H2 versus PostgreSQL for example) using distinct profiles, with the difference that here this needs to specified Ahead-Of-Time.

I am open to move forward on this proposal in the Spring Framework 6.0.x or 6.1.0 time frame, depending on the feedback from the Spring Boot team and the community.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.