Skip to content

Refine Spring profile support with AOT/native #29844

Open
@sdeleuze

Description

@sdeleuze

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.

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)theme: aotAn issue related to Ahead-of-time processingtype: enhancementA general enhancement

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions