Skip to content
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

Add support for spring-context-indexer #131

Closed
joeyvmason opened this issue Mar 1, 2018 · 10 comments
Closed

Add support for spring-context-indexer #131

joeyvmason opened this issue Mar 1, 2018 · 10 comments

Comments

@joeyvmason
Copy link
Contributor

Cold start performance for Spring applications is especially bad compared to Jersey and Spark applications. A lot of this is because Spring scans the classpath at runtime when building the application context. In Spring 5, you can configure an application to generate a static list of candidates at compilation time using spring-context-indexer. This should improve startup time significantly.

I'm not sure if code changes are required to get this working with aws-serverless-java-container or if it's as simple as just adding the dependency. At minimum, the samples and maven archetype will need to be updated.

@sapessi
Copy link
Collaborator

sapessi commented Mar 1, 2018

I've taken a quick look at this. Technically just adding the dependency should be enough for the annotation processor to run since it's defined as a service. If not, we may have to declare it explicitly in the pom file.

The next task, is to figure out how to package the generated artifact in the Lambda uber-jar and make sure that Spring can load it.

@sapessi
Copy link
Collaborator

sapessi commented Mar 16, 2018

I have started working to add the spring-context-indexer on the Spring archetype. To begin, I created a brand new app from the archetype and simply added the indexer as an optional dependency. After packaging the application (mvn package), I can see that the spring.components file was generated and included in the META-INF folder of the shaded jar and contains the expected components:

#
#Thu Mar 15 17:37:52 PDT 2018
my.service.controller.PingController=org.springframework.stereotype.Component
my.service.SpringApiConfig=org.springframework.stereotype.Component

When I tested the application using SAM Local, I saw no difference in the startup speed. Since the components are loaded from the index file, I assumed it was safe to remove the @ComponentScan annotation from my main class. However, when I do that the application responds with 404 to my requests - ie it's not picked up the routes.

  • Should @ComponentScan remain there?
  • How can I make sure that it's using the index?
  • Is there something in the way I initialize the app that's preventing it from trying to load the index?

@snicoll
Copy link

snicoll commented Mar 16, 2018

A lot of this is because Spring scans the classpath at runtime when building the application context.

What concrete evidences do you have that it is true? I had that discussion a countless number of times and very often proved classpath scanning isn't a problem at all.

Adding the indexer is an application's choice, not a library choice. And the various benchmarks we've done shows it doesn't make a difference for small to medium projects (less than 500 beans).

@snicoll
Copy link

snicoll commented Mar 16, 2018

To answer the other questions, the index is another implementation of component scan. If you remove the annotation we're obviously not going to do anything.

There is no info log for component scan. You can enable debug log and it will tell that it fetched the info from the index.

Finally, I already mentioned that classpath scanning is very fast so no surprise you don't see a difference with a small app.

@sapessi
Copy link
Collaborator

sapessi commented Mar 16, 2018

@snicoll To you first answer: I agree with you. If it makes a difference, it's only for large applications. That's why I decided to only include it in the archetypes and samples as an option (perhaps a maven profile) and not build it in the library. The main issue I'm trying to address is that some developers may not be aware of this at all, so I want to show them the option.

Good to know that CompoenentScan must still be there. That's what I was looking for. I'll test with debug logs. On a separate topic, I was trying to do the same with the Spring Boot archetype but the index was never generated. Is there something different I should do for a Spring Boot application?

@snicoll
Copy link

snicoll commented Mar 16, 2018

No.

@snicoll
Copy link

snicoll commented Mar 16, 2018

IMO it is wrong to add it to any kind of getting started infrastructure. As a user, this is not something you should care about when starting a project.

And it definitely sends the wrong message IMO.

@sapessi
Copy link
Collaborator

sapessi commented Mar 16, 2018

Interesting, I don't know enough about Spring to have a strong opinion here. Is there any downside to using the indexer @snicoll? At the moment, we just have a link to the indexer documentation in our getting started guides, would you say that's enough? What do you think @joeyvmason?

@snicoll
Copy link

snicoll commented Mar 16, 2018

IMO you shouldn't have any reference to this at all.

Again, I see no proof that it is required or that it changes anything to the startup time of an application created by the archetype. As such, I don't understand why you should be mentioning this (compared to the gazillions of features of Spring Framework you're not mentioning).

sapessi added a commit that referenced this issue Apr 5, 2018
@sapessi sapessi removed this from the Release 1.1 milestone Apr 6, 2018
@sapessi
Copy link
Collaborator

sapessi commented Jun 25, 2018

Closing this one since we have added the indexer to the samples.

@sapessi sapessi closed this as completed Jun 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants