Skip to content

please add a spring boot 3 aot support to enable graalvm use cases #2398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
joshlong opened this issue Sep 29, 2022 · 5 comments
Closed

please add a spring boot 3 aot support to enable graalvm use cases #2398

joshlong opened this issue Sep 29, 2022 · 5 comments
Labels
lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.

Comments

@joshlong
Copy link
Contributor

hi

tl;dr: my name is josh long. i work on the spring team at tanzu, a division of vmware. i would like to talk to you about contributing spring boot (3) AOT support, expanding the existing spring module. i built something like this for the older 'spring native' project and i could easily turn it into a spring boot 3 aot module.

longer story:

spring framework 6, spring boot 3, and ahead-of-time compilation

spring boot 3 (built on spring framework 6) is due sometime in november / december 2022. this year. it integrates and greatly expands/refines a lot of the ahead-of-time processing that we prototyped in a separate experimental project called spring native.

spring framework 6 has a new ahead-of-time compilation capability. it's basically a way to write code - regular components in your production spring code - that gets involved at compile-time and can contribute files that get passed into the graalvm native image compiler. spring doesn't run your full application at compile time. instead, after all the .java files have been compiled, the spring boot build plugin starts up a java process containing all the spring component configuration (such as comes from java configuration, component scanning, xml, etc.) and canonicalizes everything into the spring metamodel of BeanDefinitions, which are the things that - eventually - get turned into real 'beans' at runtime. it's at this stage, at compile-time, that spring involves your aot components. think of them like compile-time equivalents to BeanFactoryPostProcessor and BeanPostProcessors.

graalvm and spring boot 3 aot

you can get an app turned into a graalvm native image thusly: mvn -Pnative clean package or mvn -Pnative -DskipTests clean package. this should work for many classes of applications out-of-the-box, assuming the

graalvm requires configuration files (META-INF/native-image/*json) whenever you do anything at runtime that involves dynamic runtime behavior such as reflection, serialization, jdk proxies, jni, loading resources from the classpath, etc.

we use this aot capability to transform a typical spring boot application and write out configuration files for graalvm native image compilation. this automatic mechanism works for all the things over which spring has control-any beans you create, for example. but third party libraries will need to ship their own configuration. you can contribute .json files directly in the library, which get picked up by the graalvm native image compiler.

the trouble with those is that:

  • you need to make sure the string-y .json files stay in sync with the types in your codebase
  • there's no way to specify, as in a framework or library usecase, that all subclasses of a given type T should have certain configuration.

so, spring boot 3's aot component model offers an easy way forward. we can analyze the classpath, look at classes and objects in whatever way we like, and programatically register configuration to account for whatever scenario to get fed into the graalvm native image compiler.

the kubernetes java client

because of the way that the client is implemented (reflectively creating entities based on conventions with the api server), there is a lot of reflection that happens in the kubernetes java client, all of which needs to be accounted for when compiling a graalvm native image. likewise, there are a few scenarios where a client might be expected to implement or extend certain types from the kubernetes java client api. in these cases, something should contribute configuration to account for both the library and the library users' code.

benefits

graalvm native image compilation is a boon to many classes of jvm applications. i like the possibility of writing kubernetes operators and crds with the kubernetes java client. your infrastructure code shouldn't take more ram than the code it's supporting, i like to think. it's not a good look to have a jre taking a 1gb of ram to manage three 300 mb Go applications. now, with graalvm, you might get that jvm app down to 50 or 100 mb of ram, and virtually instantaneous startup. this means that people could write controllers with the spring boot and kubernetes java client integration, leverage the rich ecosystem of integrations that spring's developed over almost two decades, and then deploy that as a native binary that takes tens of megabytes of ram.

a spring native example

i already wrote the following class to use the older spring native approach . it would be trivial to port it to spring boot 3 aot

questions on support

i have to check but i think it should be possible to upgrade your spring module to spring boot 3, but introduce the new code in such a way that the regular auto configuration works when its brought into both spring boot 2 and spring boot 3 projects, and when its brought into a spring boot 3 project, the aot code also kicks in.

@joshlong joshlong changed the title please add a spring boot 3 aot module to support graalvm use cases please add a spring boot 3 aot support to enable graalvm use cases Sep 29, 2022
@brendandburns
Copy link
Contributor

@yue9944882 is the spring expert here who wrote most of the code, but from looking at this issue, it feels like something where we would be willing to accept PRs to support this.

I don't think either of us have the cycles to do the implementation.

@joshlong
Copy link
Contributor Author

joshlong commented Oct 1, 2022

fantastic. thanks for the quick reply! I'll give it a go, if there's no objection, and create a strawman PR we can improve

@k8s-triage-robot
Copy link

The Kubernetes project currently lacks enough contributors to adequately respond to all issues and PRs.

This bot triages issues and PRs according to the following rules:

  • After 90d of inactivity, lifecycle/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was applied, the issue is closed

You can:

  • Mark this issue or PR as fresh with /remove-lifecycle stale
  • Mark this issue or PR as rotten with /lifecycle rotten
  • Close this issue or PR with /close
  • Offer to help out with Issue Triage

Please send feedback to sig-contributor-experience at kubernetes/community.

/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 30, 2022
@brendandburns
Copy link
Contributor

@joshlong I believe this work item is now complete, any objections if I close this issue?

@brendandburns
Copy link
Contributor

Closing this issue as I believe it is now complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale.
Projects
None yet
Development

No branches or pull requests

4 participants