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 duplicates module/file resources #29934

Closed
Del-Tab opened this issue Feb 6, 2023 · 4 comments
Closed

PathMatchingResourcePatternResolver duplicates module/file resources #29934

Del-Tab opened this issue Feb 6, 2023 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@Del-Tab
Copy link

Del-Tab commented Feb 6, 2023

Affects: <6.0.4>

When upgrading from spring-core-5.3.24.jar to spring-core-6.0.4.jar (spring-boot 2 to 3 upgrade)

Our test uses persistence.xml descriptions for persistence units. The test fails for a duplicated persistence unit.

main cause found in debugger:
the set created at org.springframework.core.io.support.PathMatchingResourcePatternResolver#getResources line 325 with one element returned by findAllModulePathResources(locationPatternWithoutPrefix) :

  • a org.springframework.core.io.FileSystemResource whose Path (its hash source material) is /C:/SomePath/target/test-classes/META-INF/persistence.xml

then the set is completed line 332 by the result of findAllClassPathResources(locationPatternWithoutPrefix), which returns the same resource as the old version (spring-core-5.3.24):

  • an org.springframework.core.io.UrlResource whose getCleanedUrl() (its hash source material) is file:/C:/SomePath/target/test-classes/META-INF/persistence.xml (notice the file: prefix)

The found resources are the same file resource in 2 different Java structures, but their hash being solved differently, they both are added to the set, and therefore this resource conflicts with itself.

Consequence:
the method org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager#preparePersistenceUnitInfos fails the test at line 470 because the persistence units are duplicated (but they come from the same source).

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Feb 6, 2023
@Del-Tab
Copy link
Author

Del-Tab commented Feb 6, 2023

I see several ways to fix this, I think the one having less risk of consequences is cleaning the set before returning it in the PathMatchingResourcePatternResolver::getResources(String) method. But there may be more clever ways to deal with it.

If I've time (maybe next weekend) I'll write a pull request for you to decide but it looks like an easy fix.

@jhoeller jhoeller self-assigned this Feb 7, 2023
@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 Feb 7, 2023
@jhoeller jhoeller added this to the 6.0.5 milestone Feb 7, 2023
@jhoeller
Copy link
Contributor

jhoeller commented Feb 7, 2023

We have some measures in place for the automatic detection of duplicates already, in particular through conversion to FileSystemResource instead of UrlResource with a file protocol wherever possible. However, this is currently limited to our pattern matching algorithm; we seem to have missed the straight full-path case in findAllClassPathResources. As far as I see, we need to make convertClassLoaderURL perform such eager FileSystemResource conversion to cover that as well.

So thanks for the report, I'll sort this out today. Maybe you could test a 6.0.5 snapshot before the release next week then, double-checking that it works in your scenario.

@jhoeller jhoeller changed the title PathMatchingResourcePatternResolver duplicates resources PathMatchingResourcePatternResolver duplicates module/file resources Feb 7, 2023
@Del-Tab
Copy link
Author

Del-Tab commented Feb 7, 2023

As far as I see, we need to make convertClassLoaderURL perform such eager FileSystemResource conversion to cover that as well.

that's what I planned to think about in my push request :)
I'll let you fix this then :)

Maybe you could test a 6.0.5 snapshot before the release next week then, double-checking that it works in your scenario.

Unfortunately I already switched to an annotation definition for all our persistence definition, since we have an internal delivery soon and I couldn't wait (I'm working for a client so I can't really share the code for testing)
But I suppose a simple persistence.xml with a single persistentUnit object mapped shall trigger the issue.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
			 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			 version="3.0"
			 xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd">

	<persistence-unit name="my-persist-unit">
		<class>some.package.domains.SomeEntity</class>
		<properties>
			<property name="hibernate.hbm2ddl.auto" value="update"/>
		</properties>
	</persistence-unit>
</persistence>

and this in a class annoted @configuration

@Bean(name="entityManagerFactory")
public AbstractEntityManagerFactoryBean entityManagerFactoryBean(DataSource datasource) {
	LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
	factory.setDataSource(datasource);
	factory.setPersistenceUnitName("my-persist-unit");
	factory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
	return factory;
}

and the class was annoted in a DataJpaTest class

@JoeyBling
Copy link

JoeyBling commented Feb 27, 2023

The creation of an org.springframework.core.io.FileSystemResource instance in PathMatchingResourcePatternResolver#convertClassLoaderURL does not deal with special characters(Like Chinese or spaces, etc).

Maybe it should be solved as follows, buy not directly calling java.net.URL#getPath.

protected Resource convertClassLoaderURL(URL url) {
	return (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol()) ?
			new FileSystemResource(ResourceUtils.getFile(url)) : new UrlResource(url));
}

Similar problems:

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) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

4 participants