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) isfile:/C:/SomePath/target/test-classes/META-INF/persistence.xml
(notice thefile:
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).
Comment From: Del-Tab
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.
Comment From: jhoeller
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.
Comment From: Del-Tab
As far as I see, we need to make
convertClassLoaderURL
perform such eagerFileSystemResource
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
Comment From: JoeyBling
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:
- https://github.com/spring-projects/spring-boot/issues/34379
- https://github.com/spring-projects/spring-boot/issues/34364
-
30031