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

PathMatchingResourcePatternResolver regression for jar root scanning in 6.2.4 #34607

Closed
kristofdepypere opened this issue Mar 17, 2025 · 11 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: feedback-provided Feedback has been provided type: regression A bug that is also a regression
Milestone

Comments

@kristofdepypere
Copy link

kristofdepypere commented Mar 17, 2025

Hi,

We are heavily relying on the ResourceLoader and more specifically the org.springframework.core.io.support.PathMatchingResourcePatternResolver. In a legacy codebase that we own, we are using this call very often: applicationContext.getResources("classpath*:**/some-file-pattern.xml") or any other type of pattern.

Since version 6.2.4 we clearly see a difference in behavior here. Compared to version 6.2.3 we observe that now nothing is returned while it was returning the expected resources in the previous version.

We also see a difference in behavior when running locally from IntelliJ compared to running the final WAR. Running locally in IntelliJ (which is obviously more 'File based' scanning than 'Jar based' scanning) everything works. Running in the final WAR, everything fails.
As it only occurs in the final runtime, it is very difficult to analyze the Spring code to pinpoint where the difference in behavior is caused. We do see changes in org.springframework.core.io.support.PathMatchingResourcePatternResolver as of 6.2.x and a small Exception change in 6.2.4, but we couldn't point to that 100% as being the root cause.

Can you help us out here? What could have caused this difference in behavior ?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 17, 2025
@sdeleuze
Copy link
Contributor

Could you please provide a minimal reproducer as an attached project or a link to a repository allowing to see change of behavior?

@sdeleuze sdeleuze added the status: waiting-for-feedback We need additional information before we can continue label Mar 17, 2025
@kristofdepypere
Copy link
Author

That's hard. As mentioned, locally running the project will not give any insights, it only happens when running the real deal and connecting through remote debugging. The code will simply be the line shown above, the setup is highly manual anyway.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Mar 17, 2025
@jhoeller
Copy link
Contributor

jhoeller commented Mar 17, 2025

Could you try to debug through PathMatchingResourcePatternResolver.findPathMatchingResources a bit and see what happens (that is, whether it backs out of certain root paths to analyze or the like)?

Between 6.2.3 and 6.2.4, we only had one defensive change in terms of jar entries caching (#34446) which I don't see as immediately related. Maybe that specific part if worth debugging though, just in case we were missing a side effect there: see PathMatchingResourcePatternResolver.doFindPathMatchingJarResources (line 810 ff).

To be clear, PathMatchingResourcePatternResolver got quite heavily revised in 6.2 for internal jar caching. A general side effect from that effort could still be lurking here, in particular since you only experience it for war/jar scenarios, and I'd be happy to fix that for 6.2.5 based on your analysis.

@jhoeller jhoeller changed the title Issue loading ClassPathResources as of 6.2.4 PathMatchingResourcePatternResolver regression for jar root scanning in 6.2.4 Mar 17, 2025
@jhoeller jhoeller self-assigned this Mar 17, 2025
@jhoeller jhoeller added type: regression A bug that is also a regression in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Mar 17, 2025
@jhoeller jhoeller added this to the 6.2.5 milestone Mar 17, 2025
@kristofdepypere
Copy link
Author

I'll try, I already did, but I'll try more. A lot is happening there and indeed, caching is probably impacting behavior, so I only get to dive in once per application restart.

@jhoeller
Copy link
Contributor

jhoeller commented Mar 17, 2025

If that is easier to do for a start, let's double-check the behavioral difference between 6.2.3 and 6.2.4: There is just that one change in PathMatchingResourcePatternResolver mentioned above, and it'd be great to know whether that specifically causes the regression that you are experiencing, or whether the regression is somehow triggered by the general 6.2 revision before and not immediately related to that 6.2.4 change.

Aside from downgrading to 6.2.3, you could also manually patch PathMatchingResourcePatternResolver to undo that change but otherwise stay on spring-core in version 6.2.4 (since such specific patching would isolate the effect even better).

@jhoeller
Copy link
Contributor

jhoeller commented Mar 17, 2025

Potentially, this regression could also be caused by #34528 - a change in AbstractFileResolvingResource (line 87) which is called from PathMatchingResourcePatternResolver.addAllClassLoaderJarRoots (line 487). If the latter is relied on to build the initial jar roots for your scenario (that's not the common path but can happen in some scenarios), this could break the recognition of a valid jar root.

If this is the case in your scenario, we'd need to debug AbstractFileResolvingResource.exists specifically: why getInputStream() apparently fails then while the former getContentLengthLong call in 6.2.3 returned >0. This actually looks like a more likely cause to me than the PathMatchingResourcePatternResolver change mentioned above, so maybe we should investigate this one first.

Again, you could manually patch AbstractFileResolvingResource to undo that change in line 87 but otherwise stay on spring-core in version 6.2.4.

@jhoeller
Copy link
Contributor

I'm pretty sure it's a side effect from #34528. Locally reproducing it, I got a revision that makes both the original #34528 as well as the assumed .exists() check for jar roots as used in addAllClassLoaderJarRoots pass. I'll bring this into a 6.2.5 snapshot ASAP.

@kristofdepypere
Copy link
Author

@jhoeller I can confirm your hunch is correct. I tested by patching spring-core 6.2.4 with the before and after of the change in #34528 in AbstractFileResolvingResource.exists and everything works when reverting the line change.

@jhoeller
Copy link
Contributor

jhoeller commented Mar 17, 2025

Alright, thanks for double-checking! The change is pushed in the meantime, to be available in the upcoming 6.2.5-SNAPSHOT in a few minutes. Please give the snapshot a try, this is a different implementation aiming to accommodate all of the requirements.

Since this is a painful regression in the scenarios affected, we intend to release 6.2.5 out-of-cycle: this Thursday along with Boot 3.4.4. It'd be great to confirm that everything is in order before that follow-up release, so integration testing is highly appreciated.

@kristofdepypere
Copy link
Author

The 6.2.5-SNAPSHOT also works, thanks for the fix.

@jhoeller
Copy link
Contributor

Great to hear, thanks for the immediate turnaround!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: feedback-provided Feedback has been provided type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

4 participants