java
java copied to clipboard
please add a spring boot 3 aot support to enable graalvm use cases
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 BeanDefinition
s, 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 BeanPostProcessor
s.
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.
@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.
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
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
@joshlong I believe this work item is now complete, any objections if I close this issue?
Closing this issue as I believe it is now complete.