HHH-8015 Spring 3.2.1 cannot be deployed on JBoss AS7 with Hibernate 4.1.6 due to class loader issues.
This commit is contained in:
parent
52f2edfa45
commit
a6c46408df
|
@ -494,6 +494,14 @@ public interface AvailableSettings {
|
|||
*/
|
||||
public static final String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation";
|
||||
|
||||
/**
|
||||
* Used to define a {@link java.util.Collection} of the {@link ClassLoader} instances Hibernate should use for
|
||||
* class-loading and resource-lookups.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public static final String CLASSLOADERS = "hibernate.classLoaders";
|
||||
|
||||
/**
|
||||
* Names the {@link ClassLoader} used to load user application classes.
|
||||
* @since 4.0
|
||||
|
|
|
@ -23,11 +23,14 @@
|
|||
*/
|
||||
package org.hibernate.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.integrator.internal.IntegratorServiceImpl;
|
||||
import org.hibernate.integrator.spi.Integrator;
|
||||
import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
|
||||
|
||||
/**
|
||||
|
@ -40,10 +43,8 @@ import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
|
|||
*/
|
||||
public class BootstrapServiceRegistryBuilder {
|
||||
private final LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
|
||||
private ClassLoader applicationClassLoader;
|
||||
private ClassLoader resourcesClassLoader;
|
||||
private ClassLoader hibernateClassLoader;
|
||||
private ClassLoader environmentClassLoader;
|
||||
private List<ClassLoader> providedClassLoaders;
|
||||
private ClassLoaderService providedClassLoaderService;
|
||||
|
||||
/**
|
||||
* Add an {@link Integrator} to be applied to the bootstrap registry.
|
||||
|
@ -61,23 +62,56 @@ public class BootstrapServiceRegistryBuilder {
|
|||
*
|
||||
* @param classLoader The class loader to use
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@Deprecated
|
||||
public BootstrapServiceRegistryBuilder withApplicationClassLoader(ClassLoader classLoader) {
|
||||
this.applicationClassLoader = classLoader;
|
||||
return with( classLoader );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a provided {@link ClassLoader} for use in class-loading and resource-lookup
|
||||
*
|
||||
* @param classLoader The class loader to use
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public BootstrapServiceRegistryBuilder with(ClassLoader classLoader) {
|
||||
if ( providedClassLoaders == null ) {
|
||||
providedClassLoaders = new ArrayList<ClassLoader>();
|
||||
}
|
||||
providedClassLoaders.add( classLoader );
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a provided {@link ClassLoaderService} for use in class-loading and resource-lookup
|
||||
*
|
||||
* @param classLoaderService The class loader to use
|
||||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*/
|
||||
public BootstrapServiceRegistryBuilder with(ClassLoaderService classLoaderService) {
|
||||
providedClassLoaderService = classLoaderService;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Applies the specified {@link ClassLoader} as the resource class loader for the bootstrap registry
|
||||
*
|
||||
* @param classLoader The class loader to use
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
public BootstrapServiceRegistryBuilder withResourceClassLoader(ClassLoader classLoader) {
|
||||
this.resourcesClassLoader = classLoader;
|
||||
return this;
|
||||
return with( classLoader );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,11 +119,13 @@ public class BootstrapServiceRegistryBuilder {
|
|||
*
|
||||
* @param classLoader The class loader to use
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@Deprecated
|
||||
public BootstrapServiceRegistryBuilder withHibernateClassLoader(ClassLoader classLoader) {
|
||||
this.hibernateClassLoader = classLoader;
|
||||
return this;
|
||||
return with( classLoader );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,11 +133,13 @@ public class BootstrapServiceRegistryBuilder {
|
|||
*
|
||||
* @param classLoader The class loader to use
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||
*/
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@Deprecated
|
||||
public BootstrapServiceRegistryBuilder withEnvironmentClassLoader(ClassLoader classLoader) {
|
||||
this.environmentClassLoader = classLoader;
|
||||
return this;
|
||||
return with( classLoader );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,12 +148,12 @@ public class BootstrapServiceRegistryBuilder {
|
|||
* @return The built bootstrap registry
|
||||
*/
|
||||
public BootstrapServiceRegistry build() {
|
||||
final ClassLoaderServiceImpl classLoaderService = new ClassLoaderServiceImpl(
|
||||
applicationClassLoader,
|
||||
resourcesClassLoader,
|
||||
hibernateClassLoader,
|
||||
environmentClassLoader
|
||||
);
|
||||
final ClassLoaderService classLoaderService;
|
||||
if ( providedClassLoaderService == null ) {
|
||||
classLoaderService = new ClassLoaderServiceImpl( providedClassLoaders );
|
||||
} else {
|
||||
classLoaderService = providedClassLoaderService;
|
||||
}
|
||||
|
||||
final IntegratorServiceImpl integratorService = new IntegratorServiceImpl(
|
||||
providedIntegrators,
|
||||
|
|
|
@ -27,6 +27,9 @@ import java.io.IOException;
|
|||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
|
@ -35,6 +38,8 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.service.classloading.spi.ClassLoadingException;
|
||||
|
@ -45,74 +50,74 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||
private final ClassLoader classClassLoader;
|
||||
private final ClassLoader resourcesClassLoader;
|
||||
private static final Logger log = Logger.getLogger( ClassLoaderServiceImpl.class );
|
||||
|
||||
private final ClassLoader aggregatedClassLoader;
|
||||
|
||||
public ClassLoaderServiceImpl() {
|
||||
this( ClassLoaderServiceImpl.class.getClassLoader() );
|
||||
}
|
||||
|
||||
public ClassLoaderServiceImpl(ClassLoader classLoader) {
|
||||
this( classLoader, classLoader, classLoader, classLoader );
|
||||
this( Collections.singletonList( classLoader ) );
|
||||
}
|
||||
|
||||
public ClassLoaderServiceImpl(
|
||||
ClassLoader applicationClassLoader,
|
||||
ClassLoader resourcesClassLoader,
|
||||
ClassLoader hibernateClassLoader,
|
||||
ClassLoader environmentClassLoader) {
|
||||
// Normalize missing loaders
|
||||
if ( hibernateClassLoader == null ) {
|
||||
hibernateClassLoader = ClassLoaderServiceImpl.class.getClassLoader();
|
||||
}
|
||||
public ClassLoaderServiceImpl(List<ClassLoader> providedClassLoaders) {
|
||||
final LinkedHashSet<ClassLoader> orderedClassLoaderSet = new LinkedHashSet<ClassLoader>();
|
||||
|
||||
if ( environmentClassLoader == null || applicationClassLoader == null ) {
|
||||
ClassLoader sysClassLoader = locateSystemClassLoader();
|
||||
ClassLoader tccl = locateTCCL();
|
||||
if ( environmentClassLoader == null ) {
|
||||
environmentClassLoader = sysClassLoader != null ? sysClassLoader : hibernateClassLoader;
|
||||
}
|
||||
if ( applicationClassLoader == null ) {
|
||||
applicationClassLoader = tccl != null ? tccl : hibernateClassLoader;
|
||||
}
|
||||
}
|
||||
|
||||
if ( resourcesClassLoader == null ) {
|
||||
resourcesClassLoader = applicationClassLoader;
|
||||
}
|
||||
|
||||
final LinkedHashSet<ClassLoader> classLoadingClassLoaders = new LinkedHashSet<ClassLoader>();
|
||||
classLoadingClassLoaders.add( applicationClassLoader );
|
||||
classLoadingClassLoaders.add( hibernateClassLoader );
|
||||
classLoadingClassLoaders.add( environmentClassLoader );
|
||||
|
||||
this.classClassLoader = new ClassLoader(null) {
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
for ( ClassLoader loader : classLoadingClassLoaders ) {
|
||||
try {
|
||||
return loader.loadClass( name );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
// first add all provided class loaders, if any
|
||||
if ( providedClassLoaders != null ) {
|
||||
for ( ClassLoader classLoader : providedClassLoaders ) {
|
||||
if ( classLoader != null ) {
|
||||
orderedClassLoaderSet.add( classLoader );
|
||||
}
|
||||
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
this.resourcesClassLoader = resourcesClassLoader;
|
||||
// normalize adding known class-loaders...
|
||||
// first the Hibernate class loader
|
||||
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
|
||||
// then the TCCL, if one...
|
||||
final ClassLoader tccl = locateTCCL();
|
||||
if ( tccl != null ) {
|
||||
orderedClassLoaderSet.add( tccl );
|
||||
}
|
||||
// finally the system classloader
|
||||
final ClassLoader sysClassLoader = locateSystemClassLoader();
|
||||
if ( sysClassLoader != null ) {
|
||||
orderedClassLoaderSet.add( sysClassLoader );
|
||||
}
|
||||
|
||||
// now build the aggregated class loader...
|
||||
this.aggregatedClassLoader = new AggregatedClassLoader( orderedClassLoaderSet );
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
@SuppressWarnings({"UnusedDeclaration", "unchecked", "deprecation"})
|
||||
@Deprecated
|
||||
public static ClassLoaderServiceImpl fromConfigSettings(Map configVales) {
|
||||
return new ClassLoaderServiceImpl(
|
||||
(ClassLoader) configVales.get( AvailableSettings.APP_CLASSLOADER ),
|
||||
(ClassLoader) configVales.get( AvailableSettings.RESOURCES_CLASSLOADER ),
|
||||
(ClassLoader) configVales.get( AvailableSettings.HIBERNATE_CLASSLOADER ),
|
||||
(ClassLoader) configVales.get( AvailableSettings.ENVIRONMENT_CLASSLOADER )
|
||||
);
|
||||
final List<ClassLoader> providedClassLoaders = new ArrayList<ClassLoader>();
|
||||
|
||||
final Collection<ClassLoader> classLoaders = (Collection<ClassLoader>) configVales.get( AvailableSettings.CLASSLOADERS );
|
||||
if ( classLoaders != null ) {
|
||||
for ( ClassLoader classLoader : classLoaders ) {
|
||||
providedClassLoaders.add( classLoader );
|
||||
}
|
||||
}
|
||||
|
||||
addIfSet( providedClassLoaders, AvailableSettings.APP_CLASSLOADER, configVales );
|
||||
addIfSet( providedClassLoaders, AvailableSettings.RESOURCES_CLASSLOADER, configVales );
|
||||
addIfSet( providedClassLoaders, AvailableSettings.HIBERNATE_CLASSLOADER, configVales );
|
||||
addIfSet( providedClassLoaders, AvailableSettings.ENVIRONMENT_CLASSLOADER, configVales );
|
||||
|
||||
return new ClassLoaderServiceImpl( providedClassLoaders );
|
||||
}
|
||||
|
||||
private static void addIfSet(List<ClassLoader> providedClassLoaders, String name, Map configVales) {
|
||||
final ClassLoader providedClassLoader = (ClassLoader) configVales.get( name );
|
||||
if ( providedClassLoader != null ) {
|
||||
providedClassLoaders.add( providedClassLoader );
|
||||
}
|
||||
}
|
||||
private static ClassLoader locateSystemClassLoader() {
|
||||
try {
|
||||
return ClassLoader.getSystemClassLoader();
|
||||
|
@ -135,7 +140,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> Class<T> classForName(String className) {
|
||||
try {
|
||||
return (Class<T>) Class.forName( className, true, classClassLoader );
|
||||
return (Class<T>) Class.forName( className, true, aggregatedClassLoader );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
|
||||
|
@ -152,7 +157,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
}
|
||||
|
||||
try {
|
||||
return resourcesClassLoader.getResource( name );
|
||||
return aggregatedClassLoader.getResource( name );
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
|
@ -164,17 +169,43 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
public InputStream locateResourceStream(String name) {
|
||||
// first we try name as a URL
|
||||
try {
|
||||
log.tracef( "trying via [new URL(\"%s\")]", name );
|
||||
return new URL( name ).openStream();
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
|
||||
try {
|
||||
return resourcesClassLoader.getResourceAsStream( name );
|
||||
log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", name );
|
||||
InputStream stream = aggregatedClassLoader.getResourceAsStream( name );
|
||||
if ( stream != null ) {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
|
||||
final String stripped = name.startsWith( "/" ) ? name.substring(1) : null;
|
||||
|
||||
if ( stripped != null ) {
|
||||
try {
|
||||
log.tracef( "trying via [new URL(\"%s\")]", stripped );
|
||||
return new URL( stripped ).openStream();
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
|
||||
try {
|
||||
log.tracef( "trying via [ClassLoader.getResourceAsStream(\"%s\")]", stripped );
|
||||
InputStream stream = aggregatedClassLoader.getResourceAsStream( stripped );
|
||||
if ( stream != null ) {
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
catch ( Exception ignore ) {
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -182,7 +213,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
public List<URL> locateResources(String name) {
|
||||
ArrayList<URL> urls = new ArrayList<URL>();
|
||||
try {
|
||||
Enumeration<URL> urlEnumeration = resourcesClassLoader.getResources( name );
|
||||
Enumeration<URL> urlEnumeration = aggregatedClassLoader.getResources( name );
|
||||
if ( urlEnumeration != null && urlEnumeration.hasMoreElements() ) {
|
||||
while ( urlEnumeration.hasMoreElements() ) {
|
||||
urls.add( urlEnumeration.nextElement() );
|
||||
|
@ -197,56 +228,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
|
||||
@Override
|
||||
public <S> LinkedHashSet<S> loadJavaServices(Class<S> serviceContract) {
|
||||
final ClassLoader serviceLoaderClassLoader = new ClassLoader(null) {
|
||||
final ClassLoader[] classLoaderArray = new ClassLoader[] {
|
||||
// first look on the hibernate class loader
|
||||
getClass().getClassLoader(),
|
||||
// next look on the resource class loader
|
||||
resourcesClassLoader,
|
||||
// finally look on the combined class class loader
|
||||
classClassLoader
|
||||
};
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
final HashSet<URL> resourceUrls = new HashSet<URL>();
|
||||
|
||||
for ( ClassLoader classLoader : classLoaderArray ) {
|
||||
final Enumeration<URL> urls = classLoader.getResources( name );
|
||||
while ( urls.hasMoreElements() ) {
|
||||
resourceUrls.add( urls.nextElement() );
|
||||
}
|
||||
}
|
||||
|
||||
return new Enumeration<URL>() {
|
||||
final Iterator<URL> resourceUrlIterator = resourceUrls.iterator();
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return resourceUrlIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
return resourceUrlIterator.next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
for ( ClassLoader classLoader : classLoaderArray ) {
|
||||
try {
|
||||
return classLoader.loadClass( name );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
||||
}
|
||||
};
|
||||
|
||||
final ServiceLoader<S> loader = ServiceLoader.load( serviceContract, serviceLoaderClassLoader );
|
||||
final ServiceLoader<S> loader = ServiceLoader.load( serviceContract, aggregatedClassLoader );
|
||||
final LinkedHashSet<S> services = new LinkedHashSet<S>();
|
||||
for ( S service : loader ) {
|
||||
services.add( service );
|
||||
|
@ -254,4 +236,62 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
|||
|
||||
return services;
|
||||
}
|
||||
private static class AggregatedClassLoader extends ClassLoader {
|
||||
private final ClassLoader[] individualClassLoaders;
|
||||
|
||||
private AggregatedClassLoader(final LinkedHashSet<ClassLoader> orderedClassLoaderSet) {
|
||||
super( null );
|
||||
individualClassLoaders = orderedClassLoaderSet.toArray( new ClassLoader[ orderedClassLoaderSet.size() ] );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<URL> getResources(String name) throws IOException {
|
||||
final HashSet<URL> resourceUrls = new HashSet<URL>();
|
||||
|
||||
for ( ClassLoader classLoader : individualClassLoaders ) {
|
||||
final Enumeration<URL> urls = classLoader.getResources( name );
|
||||
while ( urls.hasMoreElements() ) {
|
||||
resourceUrls.add( urls.nextElement() );
|
||||
}
|
||||
}
|
||||
|
||||
return new Enumeration<URL>() {
|
||||
final Iterator<URL> resourceUrlIterator = resourceUrls.iterator();
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return resourceUrlIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL nextElement() {
|
||||
return resourceUrlIterator.next();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected URL findResource(String name) {
|
||||
for ( ClassLoader classLoader : individualClassLoaders ) {
|
||||
final URL resource = classLoader.getResource( name );
|
||||
if ( resource != null ) {
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
return super.findResource( name );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
for ( ClassLoader classLoader : individualClassLoaders ) {
|
||||
try {
|
||||
return classLoader.loadClass( name );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException( "Could not load requested class : " + name );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue