The Spring Context indexer was introduced as a way to process component scanning of very large applications at build-time. It comes with several limitations, the biggest one being an on/off switch (i.e. as soon as one metadata file is present, all jar files must have been processed with the tool or matching beans won't be found).
In the meantime, our AOT efforts in Spring Framework 6 covers those performance and build-time optimization aspects in a much broader fashion. As we don't intend to further explore the route of the indexer, we're going to deprecate it in favor of AOT.
Comment From: mitasov-ra
Does Spring AOT imply GraalVM usage?
Comment From: snicoll
No.
Comment From: vpavic
It's a shame to see the indexer deprecated (and eventually removed) since it was quite useful in some situations and provided measurable gains during startup.
For older (and larger) applications I don't know how feasible will it be to move to AOT - I would even say that the type of applications that benefited the most from the indexer are the ones least likely to adopt AOT. But also with the new applications I personally don't like being forced to adopt AOT to have optimization of this kind at disposal.
Did indexer incur so much maintenance cost?
Comment From: snicoll
It's not so much the maintenance cost, but rather the fact that the indexer has serious limitations and we know we won't be resolving them. I can see how that can be annoying if it is working fine for you as it is, but, as maintainers, we have to strike a balance between "competing" options, the message it sends and the confusion it could bring.
AOT is not set in stone, far from it. It would be interesting to see how it could be used to handle what the indexer used to do, with less optimizations and therefore more flexibility at runtime.
That being said, we can't remove the indexer before 7.0 at the earliest. We're monitoring this issue and we'll review our position before M1 if necessary.
Comment From: vpavic
FWIW, it seems to me that support for JVM Checkpoint Restore (using CRaC) is perhaps better suited to be considered as the feature that context indexer is deprecated in favor of, simply because it allows developers to continue building their applications as they are used to (unlike AOT).
Comment From: sdeleuze
CRaC has great benefits, but I think it introduces more constraints than AOT (some like fixed application context being common), and has a different nature, so I tend to agree with the line of thinking that AOT is conceptually the successor of the context indexer.
Comment From: shodo
@snicoll I've started to check how to optimize spring-boot startup times and landed on articles about the context-indexer.
I've gained around ~6 seconds on my machine following the most straightforward tutorial I've found.
Then I found this deprecation issue and tried AOT expecting similar or even better performance but I've gained nothing using it.
What I've tried is basically to build with spring-boot:process-aot
and run the jar with -Dspring.aot.enabled=true
(on JRE, not as native image)
So: - is that AOT does not help as the context-indexer in reducing startup times without going native? In that case, I don't see why set the indexer as deprecated. - or Is it that I'm using it in the wrong manner? I honestly find it very difficult to understand how it works and all the necessary steps to reduce startup times. In this sense, the context-indexer was really more straightforward to use.
Comment From: bclozel
@shodo it's hard to answer your comment without knowing why the context indexer worked in the first place. How many beans does your application has? Is I/O (classpath scanning) really slow on your target system?
In theory, the context indexer skips the classpath scanning phase and lists the bean classes in a flat file. During startup, Spring will still have to introspect classes, parse configuration classes, create bean definitions and finally create beans. AOT processing performs a lot of work at build time - during startup, the beans definitions are registered directly; skipping all previous tasks. It is quite surprising to not get additional benefits compared to the context indexer.
You could try and share with us a sample application so we can better understand the problem. You don't have to share your production app, but a simple application that reproduces the symptomatic behavior (lots of beans, lots of configuration classes, etc).
Comment From: shodo
Ok, this weekend I'll try to setup a pet project, hoping it will show similar results.
Comment From: shodo
Hi @bclozel I've finally created a fake/dummy service that (at least on my PC) shows result similar to our production service. The repo is available here: https://github.com/shodo/fake-service
There is a readme that explain a little bit how is structured and how to run it, the result I'm obtaining are the following:
- standard mode: c.g.s.f.webapp.FakeServiceApplicationKt : Started FakeServiceApplicationKt in 13.056 seconds (process running for 14.914)
- indexer mode: c.g.s.f.webapp.FakeServiceApplicationKt : Started FakeServiceApplicationKt in 8.805 seconds (process running for 9.753)
- AOT mode: c.g.s.f.webapp.FakeServiceApplicationKt : Started FakeServiceApplicationKt in 13.984 seconds (process running for 14.813)
I've done many runs, the AOT one seems the most variable, some time 11seconds, some time 16seconds, while the standard and the indexer are more stable.
Comment From: bclozel
@shodo the sample application is quite complex and there are a lot of moving parts. The problem might be in the build configuration itself. I'm moving this to a new issue #31307 as it's not related to this particular issue.
Comment From: ascopes
@snicoll Unless I misunderstand...
At the moment, AOT is focused on allowing Spring applications to be deployed as native images using GraalVM. We intend to support more JVM-based use cases in future generations.
Doesn't this imply you do need GraalVM currently?
Comment From: sbrannen
Doesn't this imply you do need GraalVM currently?
No. Previously the "focus" was primarily for use with a GraalVM native image, but it was always possible to use Spring AOT on the JVM, and Spring Framework 6.1 and future generations will provide more first-class support for JVM-based use cases such as CDS (class data sharing), Project Leyden, etc.
Though, you're right: the wording in that note in the reference manual could be improved to make this clearer.
@ascopes, would you like to open an issue to address that topic?
Comment From: ascopes
Thanks for the quick response!
I'll have to see if I have some time at the weekend to throw something together, but happy to take a look!