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

Cache-busting does not work when lazy-initialization is enabled #25488

Closed
black-snow opened this issue May 6, 2020 · 3 comments
Closed

Cache-busting does not work when lazy-initialization is enabled #25488

black-snow opened this issue May 6, 2020 · 3 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Milestone

Comments

@black-snow
Copy link

Original issue here: thymeleaf/thymeleaf-spring#227

It seems like cache-busting does not work when lazy initialization is active. Once I set it to false cache-busting works again.
This seems like a bug for the docs say:

In a web application, enabling lazy initialization will result in many web-related beans not being initialized until an HTTP request is received.

But this does not seem to be true for whatever component is responsible for spring.resources.chain.strategy.content.

Spring boot versions tested: 2.2.2 and 2.2.6
Tested with Thymeleaf

Miminal setup:

Check out https://github.com/ultraq/gs-serving-web-content/tree/cache-busting-issue/complete (branch cache-busting-issue).

In application.properties:

spring.resources.cache.cachecontrol.max-age=604800
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.html-application-cache=true

# toggle this on/off
#spring.main.lazy-initialization=true

Maybe this behaviour is intended / to be expected - if so please add a paragraph to the docs.

@wilkinsona
Copy link
Member

When resourceHandlerMapping is lazy, ResourceUrlProvider.detectResourceHandlers(ApplicationContext) doesn't find it and, therefore, can't extract its ResourceHttpRequestHandlers. This leaves it with an empty handlerMap so getForLookupPath(String) can't get the handler's ResourceResolverChain and use it for URL path resolution.

The problem can be worked around by ensuring that resourceHandlerMapping is eagerly initialised:

@Bean
public LazyInitializationExcludeFilter eagerResourceHandlerMapping() {
    return (name, definition, type) -> "resourceHandlerMapping".equals(name);
}

@wilkinsona
Copy link
Member

I think this may be a Framework bug. WebMvcConfigurationSupport defines resourceHandlerMapping as a HandlerMapping yet ResourceUrlProvider.detectResourceHandlers(ApplicationContext) tries to discover it by looking for SimpleUrlHandlerMapping beans. This means that the resource handler detection relies upon being called after resourceHandlerMapping has been created so that the bean factory can identify that it's a SimpleUrlHandlerMapper rather than the less-specific HandlerMapping that it is defined as.

I think a similar problem could arise without lazy init if WebMvcConfigurationSupport was sub-classed and resourceHandlerMapping was overridden to return a HandlerMapping that isn't a SimpleUrlHandlerMapping. That would prevent ResourceUrlProvider.detectResourceHandlers(ApplicationContext) from finding it, even if it was an AbstractUrlHandlerMapping that defines the getHandlerMap() method that resource handler detection requires.

I wonder if detectResourceHandlers(ApplicationContext) should get all HandlerMapping beans, filter out those that are not an AbstractUrlHandlerMapping or perhaps SimpleUrlHandlerMapping, and then proceed with extracting the ResourceHttpRequestHandlers as it does at the moment.

@bclozel bclozel transferred this issue from spring-projects/spring-boot Jul 29, 2020
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jul 29, 2020
@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Nov 10, 2021
@snicoll snicoll added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Nov 22, 2023
@snicoll snicoll self-assigned this Nov 22, 2023
@snicoll snicoll added this to the 6.1.2 milestone Nov 22, 2023
snicoll added a commit to snicoll/spring-framework that referenced this issue Nov 22, 2023
This commit makes sure to initialize any HandlerMapping defined in the
context when searching for resource handlers. Previously, the detection
algorithm was looking up for `SimpleUrlHandlerMapping` while the
declared target type in WebMvcConfigurationSupport is HandlerMapping.
If the application uses lazy initialization, the lookup algorithm would
not force that bean to be initialized.

Closes spring-projectsgh-25488
@snicoll
Copy link
Member

snicoll commented Nov 22, 2023

I've pushed a proposal for this in snicoll@33d15dd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: bug A general bug
Projects
None yet
Development

No branches or pull requests

5 participants