HHH-12979 - Setting hibernate.javax.cache.uri property value as relative path causes an error
Resolve the hibernate.javax.cache.uri using the ClassLoaderService. Strip the classpath:// prefix if not resolved by new URL() in ClassLoaderService. This way, if a framework (e.g. Spring) has installed a handler for classpath://, the resource is resolved with its handler and class loader. If not, we remove the classpath:// prefix and we resolve the resource with our classloader.
This commit is contained in:
parent
fecb12cff7
commit
52e72f5d38
|
@ -39,6 +39,8 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
|
||||
private static final CoreMessageLogger log = CoreLogging.messageLogger( ClassLoaderServiceImpl.class );
|
||||
|
||||
private static final String CLASS_PATH_SCHEME = "classpath://";
|
||||
|
||||
private final ConcurrentMap<Class, ServiceLoader> serviceLoaders = new ConcurrentHashMap<Class, ServiceLoader>();
|
||||
private volatile AggregatedClassLoader aggregatedClassLoader;
|
||||
|
||||
|
@ -147,6 +149,10 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
// if we couldn't find the resource containing a classpath:// prefix above, that means we don't have a URL
|
||||
// handler for it. So let's remove the prefix and resolve against our class loader.
|
||||
name = stripClasspathScheme( name );
|
||||
|
||||
try {
|
||||
final URL url = getAggregatedClassLoader().getResource( name );
|
||||
if ( url != null ) {
|
||||
|
@ -182,6 +188,10 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
// if we couldn't find the resource containing a classpath:// prefix above, that means we don't have a URL
|
||||
// handler for it. So let's remove the prefix and resolve against our class loader.
|
||||
name = stripClasspathScheme( name );
|
||||
|
||||
try {
|
||||
log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", name );
|
||||
final InputStream stream = getAggregatedClassLoader().getResourceAsStream( name );
|
||||
|
@ -271,6 +281,18 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
return aggregated;
|
||||
}
|
||||
|
||||
private String stripClasspathScheme(String name) {
|
||||
if ( name == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( name.startsWith( CLASS_PATH_SCHEME ) ) {
|
||||
return name.substring( CLASS_PATH_SCHEME.length() );
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
for ( ServiceLoader serviceLoader : serviceLoaders.values() ) {
|
||||
|
|
|
@ -8,8 +8,10 @@ package org.hibernate.cache.jcache.internal;
|
|||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.cache.Cache;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
|
@ -31,7 +33,6 @@ import org.hibernate.cache.spi.support.DomainDataStorageAccess;
|
|||
import org.hibernate.cache.spi.support.RegionFactoryTemplate;
|
||||
import org.hibernate.cache.spi.support.RegionNameQualifier;
|
||||
import org.hibernate.cache.spi.support.StorageAccess;
|
||||
import org.hibernate.cache.spi.support.DomainDataRegionImpl;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
|
@ -203,7 +204,7 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
|
|||
|
||||
final CachingProvider cachingProvider = getCachingProvider( properties );
|
||||
final CacheManager cacheManager;
|
||||
final URI cacheManagerUri = getUri( properties );
|
||||
final URI cacheManagerUri = getUri( settings, properties );
|
||||
if ( cacheManagerUri != null ) {
|
||||
cacheManager = cachingProvider.getCacheManager( cacheManagerUri, getClassLoader( cachingProvider ));
|
||||
}
|
||||
|
@ -219,18 +220,25 @@ public class JCacheRegionFactory extends RegionFactoryTemplate {
|
|||
return cachingProvider.getDefaultClassLoader();
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
protected URI getUri(Map properties) {
|
||||
protected URI getUri(SessionFactoryOptions settings, Map properties) {
|
||||
String cacheManagerUri = getProp( properties, ConfigSettings.CONFIG_URI );
|
||||
if ( cacheManagerUri == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return new URI( cacheManagerUri );
|
||||
URL url = settings.getServiceRegistry()
|
||||
.getService( ClassLoaderService.class )
|
||||
.locateResource( cacheManagerUri );
|
||||
|
||||
if ( url == null ) {
|
||||
throw new CacheException( "Couldn't load URI from " + cacheManagerUri );
|
||||
}
|
||||
catch ( URISyntaxException e ) {
|
||||
throw new CacheException( "Couldn't create URI from " + cacheManagerUri, e );
|
||||
|
||||
try {
|
||||
return url.toURI();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
throw new CacheException( "Couldn't load URI from " + cacheManagerUri, e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cache.jcache.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.cache.jcache.ConfigSettings;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
|
||||
public class JCacheClasspathConfigUriTest
|
||||
extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected void addSettings(Map settings) {
|
||||
settings.put( Environment.CACHE_REGION_FACTORY, "jcache" );
|
||||
settings.put( ConfigSettings.CONFIG_URI, "classpath://hibernate-config/ehcache/jcache-ehcache-config.xml" );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[]{
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Product product = new Product();
|
||||
product.setName( "Acme" );
|
||||
product.setPriceCents( 100L );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
session.persist( product );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cache.jcache.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.cache.jcache.ConfigSettings;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
|
||||
public class JCacheConfigRelativePathTest
|
||||
extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected void addSettings(Map settings) {
|
||||
settings.put( Environment.CACHE_REGION_FACTORY, "jcache" );
|
||||
settings.put( ConfigSettings.CONFIG_URI, "/hibernate-config/ehcache/jcache-ehcache-config.xml" );
|
||||
}
|
||||
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Product product = new Product();
|
||||
product.setName( "Acme" );
|
||||
product.setPriceCents( 100L );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
session.persist( product );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
48
hibernate-jcache/src/test/java/org/hibernate/test/cache/jcache/config/JCacheConfigUrlTest.java
vendored
Normal file
48
hibernate-jcache/src/test/java/org/hibernate/test/cache/jcache/config/JCacheConfigUrlTest.java
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cache.jcache.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.hibernate.cache.jcache.ConfigSettings;
|
||||
import org.hibernate.cfg.Environment;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
|
||||
public class JCacheConfigUrlTest
|
||||
extends BaseNonConfigCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
protected void addSettings(Map settings) {
|
||||
settings.put( Environment.CACHE_REGION_FACTORY, "jcache" );
|
||||
settings.put(
|
||||
ConfigSettings.CONFIG_URI,
|
||||
"file://" + Thread.currentThread().getContextClassLoader().getResource( "hibernate-config/ehcache/jcache-ehcache-config.xml" ).getPath()
|
||||
);
|
||||
}
|
||||
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
Product.class
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
Product product = new Product();
|
||||
product.setName( "Acme" );
|
||||
product.setPriceCents( 100L );
|
||||
|
||||
doInHibernate( this::sessionFactory, session -> {
|
||||
session.persist( product );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
50
hibernate-jcache/src/test/java/org/hibernate/test/cache/jcache/config/Product.java
vendored
Normal file
50
hibernate-jcache/src/test/java/org/hibernate/test/cache/jcache/config/Product.java
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.test.cache.jcache.config;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Vlad Mihalcea
|
||||
*/
|
||||
@Entity(name = "Parent")
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private Long priceCents;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getPriceCents() {
|
||||
return priceCents;
|
||||
}
|
||||
|
||||
public void setPriceCents(Long priceCents) {
|
||||
this.priceCents = priceCents;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<config
|
||||
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
|
||||
xmlns='http://www.ehcache.org/v3'
|
||||
xsi:schemaLocation="
|
||||
http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">
|
||||
|
||||
<cache alias="ready-cache">
|
||||
<key-type>java.lang.Long</key-type>
|
||||
<value-type>org.hibernate.test.cache.jcache.config.Product</value-type>
|
||||
<heap unit="entries">100</heap>
|
||||
</cache>
|
||||
|
||||
</config>
|
Loading…
Reference in New Issue