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";
|
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.
|
* Names the {@link ClassLoader} used to load user application classes.
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
|
|
|
@ -23,11 +23,14 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.service;
|
package org.hibernate.service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.integrator.internal.IntegratorServiceImpl;
|
import org.hibernate.integrator.internal.IntegratorServiceImpl;
|
||||||
import org.hibernate.integrator.spi.Integrator;
|
import org.hibernate.integrator.spi.Integrator;
|
||||||
import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl;
|
import org.hibernate.service.classloading.internal.ClassLoaderServiceImpl;
|
||||||
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
|
import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,10 +43,8 @@ import org.hibernate.service.internal.BootstrapServiceRegistryImpl;
|
||||||
*/
|
*/
|
||||||
public class BootstrapServiceRegistryBuilder {
|
public class BootstrapServiceRegistryBuilder {
|
||||||
private final LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
|
private final LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
|
||||||
private ClassLoader applicationClassLoader;
|
private List<ClassLoader> providedClassLoaders;
|
||||||
private ClassLoader resourcesClassLoader;
|
private ClassLoaderService providedClassLoaderService;
|
||||||
private ClassLoader hibernateClassLoader;
|
|
||||||
private ClassLoader environmentClassLoader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an {@link Integrator} to be applied to the bootstrap registry.
|
* 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
|
* @param classLoader The class loader to use
|
||||||
* @return {@code this}, for method chaining
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings( {"UnusedDeclaration"})
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
|
@Deprecated
|
||||||
public BootstrapServiceRegistryBuilder withApplicationClassLoader(ClassLoader classLoader) {
|
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;
|
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
|
* Applies the specified {@link ClassLoader} as the resource class loader for the bootstrap registry
|
||||||
*
|
*
|
||||||
* @param classLoader The class loader to use
|
* @param classLoader The class loader to use
|
||||||
* @return {@code this}, for method chaining
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@SuppressWarnings( {"UnusedDeclaration"})
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
public BootstrapServiceRegistryBuilder withResourceClassLoader(ClassLoader classLoader) {
|
public BootstrapServiceRegistryBuilder withResourceClassLoader(ClassLoader classLoader) {
|
||||||
this.resourcesClassLoader = classLoader;
|
return with( classLoader );
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,11 +119,13 @@ public class BootstrapServiceRegistryBuilder {
|
||||||
*
|
*
|
||||||
* @param classLoader The class loader to use
|
* @param classLoader The class loader to use
|
||||||
* @return {@code this}, for method chaining
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings( {"UnusedDeclaration"})
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
|
@Deprecated
|
||||||
public BootstrapServiceRegistryBuilder withHibernateClassLoader(ClassLoader classLoader) {
|
public BootstrapServiceRegistryBuilder withHibernateClassLoader(ClassLoader classLoader) {
|
||||||
this.hibernateClassLoader = classLoader;
|
return with( classLoader );
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,11 +133,13 @@ public class BootstrapServiceRegistryBuilder {
|
||||||
*
|
*
|
||||||
* @param classLoader The class loader to use
|
* @param classLoader The class loader to use
|
||||||
* @return {@code this}, for method chaining
|
* @return {@code this}, for method chaining
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link #with(ClassLoader)} instead
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings( {"UnusedDeclaration"})
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
|
@Deprecated
|
||||||
public BootstrapServiceRegistryBuilder withEnvironmentClassLoader(ClassLoader classLoader) {
|
public BootstrapServiceRegistryBuilder withEnvironmentClassLoader(ClassLoader classLoader) {
|
||||||
this.environmentClassLoader = classLoader;
|
return with( classLoader );
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,12 +148,12 @@ public class BootstrapServiceRegistryBuilder {
|
||||||
* @return The built bootstrap registry
|
* @return The built bootstrap registry
|
||||||
*/
|
*/
|
||||||
public BootstrapServiceRegistry build() {
|
public BootstrapServiceRegistry build() {
|
||||||
final ClassLoaderServiceImpl classLoaderService = new ClassLoaderServiceImpl(
|
final ClassLoaderService classLoaderService;
|
||||||
applicationClassLoader,
|
if ( providedClassLoaderService == null ) {
|
||||||
resourcesClassLoader,
|
classLoaderService = new ClassLoaderServiceImpl( providedClassLoaders );
|
||||||
hibernateClassLoader,
|
} else {
|
||||||
environmentClassLoader
|
classLoaderService = providedClassLoaderService;
|
||||||
);
|
}
|
||||||
|
|
||||||
final IntegratorServiceImpl integratorService = new IntegratorServiceImpl(
|
final IntegratorServiceImpl integratorService = new IntegratorServiceImpl(
|
||||||
providedIntegrators,
|
providedIntegrators,
|
||||||
|
|
|
@ -27,6 +27,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -35,6 +38,8 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.service.classloading.spi.ClassLoadingException;
|
import org.hibernate.service.classloading.spi.ClassLoadingException;
|
||||||
|
@ -45,74 +50,74 @@ import org.hibernate.service.classloading.spi.ClassLoadingException;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class ClassLoaderServiceImpl implements ClassLoaderService {
|
public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
private final ClassLoader classClassLoader;
|
private static final Logger log = Logger.getLogger( ClassLoaderServiceImpl.class );
|
||||||
private final ClassLoader resourcesClassLoader;
|
|
||||||
|
private final ClassLoader aggregatedClassLoader;
|
||||||
|
|
||||||
public ClassLoaderServiceImpl() {
|
public ClassLoaderServiceImpl() {
|
||||||
this( ClassLoaderServiceImpl.class.getClassLoader() );
|
this( ClassLoaderServiceImpl.class.getClassLoader() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoaderServiceImpl(ClassLoader classLoader) {
|
public ClassLoaderServiceImpl(ClassLoader classLoader) {
|
||||||
this( classLoader, classLoader, classLoader, classLoader );
|
this( Collections.singletonList( classLoader ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassLoaderServiceImpl(
|
public ClassLoaderServiceImpl(List<ClassLoader> providedClassLoaders) {
|
||||||
ClassLoader applicationClassLoader,
|
final LinkedHashSet<ClassLoader> orderedClassLoaderSet = new LinkedHashSet<ClassLoader>();
|
||||||
ClassLoader resourcesClassLoader,
|
|
||||||
ClassLoader hibernateClassLoader,
|
|
||||||
ClassLoader environmentClassLoader) {
|
|
||||||
// Normalize missing loaders
|
|
||||||
if ( hibernateClassLoader == null ) {
|
|
||||||
hibernateClassLoader = ClassLoaderServiceImpl.class.getClassLoader();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( environmentClassLoader == null || applicationClassLoader == null ) {
|
// first add all provided class loaders, if any
|
||||||
ClassLoader sysClassLoader = locateSystemClassLoader();
|
if ( providedClassLoaders != null ) {
|
||||||
ClassLoader tccl = locateTCCL();
|
for ( ClassLoader classLoader : providedClassLoaders ) {
|
||||||
if ( environmentClassLoader == null ) {
|
if ( classLoader != null ) {
|
||||||
environmentClassLoader = sysClassLoader != null ? sysClassLoader : hibernateClassLoader;
|
orderedClassLoaderSet.add( classLoader );
|
||||||
}
|
|
||||||
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) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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) {
|
public static ClassLoaderServiceImpl fromConfigSettings(Map configVales) {
|
||||||
return new ClassLoaderServiceImpl(
|
final List<ClassLoader> providedClassLoaders = new ArrayList<ClassLoader>();
|
||||||
(ClassLoader) configVales.get( AvailableSettings.APP_CLASSLOADER ),
|
|
||||||
(ClassLoader) configVales.get( AvailableSettings.RESOURCES_CLASSLOADER ),
|
final Collection<ClassLoader> classLoaders = (Collection<ClassLoader>) configVales.get( AvailableSettings.CLASSLOADERS );
|
||||||
(ClassLoader) configVales.get( AvailableSettings.HIBERNATE_CLASSLOADER ),
|
if ( classLoaders != null ) {
|
||||||
(ClassLoader) configVales.get( AvailableSettings.ENVIRONMENT_CLASSLOADER )
|
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() {
|
private static ClassLoader locateSystemClassLoader() {
|
||||||
try {
|
try {
|
||||||
return ClassLoader.getSystemClassLoader();
|
return ClassLoader.getSystemClassLoader();
|
||||||
|
@ -135,7 +140,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
@SuppressWarnings( {"unchecked"})
|
@SuppressWarnings( {"unchecked"})
|
||||||
public <T> Class<T> classForName(String className) {
|
public <T> Class<T> classForName(String className) {
|
||||||
try {
|
try {
|
||||||
return (Class<T>) Class.forName( className, true, classClassLoader );
|
return (Class<T>) Class.forName( className, true, aggregatedClassLoader );
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
|
throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
|
||||||
|
@ -152,7 +157,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return resourcesClassLoader.getResource( name );
|
return aggregatedClassLoader.getResource( name );
|
||||||
}
|
}
|
||||||
catch ( Exception ignore ) {
|
catch ( Exception ignore ) {
|
||||||
}
|
}
|
||||||
|
@ -164,17 +169,43 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
public InputStream locateResourceStream(String name) {
|
public InputStream locateResourceStream(String name) {
|
||||||
// first we try name as a URL
|
// first we try name as a URL
|
||||||
try {
|
try {
|
||||||
|
log.tracef( "trying via [new URL(\"%s\")]", name );
|
||||||
return new URL( name ).openStream();
|
return new URL( name ).openStream();
|
||||||
}
|
}
|
||||||
catch ( Exception ignore ) {
|
catch ( Exception ignore ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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 ) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +213,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
public List<URL> locateResources(String name) {
|
public List<URL> locateResources(String name) {
|
||||||
ArrayList<URL> urls = new ArrayList<URL>();
|
ArrayList<URL> urls = new ArrayList<URL>();
|
||||||
try {
|
try {
|
||||||
Enumeration<URL> urlEnumeration = resourcesClassLoader.getResources( name );
|
Enumeration<URL> urlEnumeration = aggregatedClassLoader.getResources( name );
|
||||||
if ( urlEnumeration != null && urlEnumeration.hasMoreElements() ) {
|
if ( urlEnumeration != null && urlEnumeration.hasMoreElements() ) {
|
||||||
while ( urlEnumeration.hasMoreElements() ) {
|
while ( urlEnumeration.hasMoreElements() ) {
|
||||||
urls.add( urlEnumeration.nextElement() );
|
urls.add( urlEnumeration.nextElement() );
|
||||||
|
@ -197,56 +228,7 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <S> LinkedHashSet<S> loadJavaServices(Class<S> serviceContract) {
|
public <S> LinkedHashSet<S> loadJavaServices(Class<S> serviceContract) {
|
||||||
final ClassLoader serviceLoaderClassLoader = new ClassLoader(null) {
|
final ServiceLoader<S> loader = ServiceLoader.load( serviceContract, aggregatedClassLoader );
|
||||||
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 LinkedHashSet<S> services = new LinkedHashSet<S>();
|
final LinkedHashSet<S> services = new LinkedHashSet<S>();
|
||||||
for ( S service : loader ) {
|
for ( S service : loader ) {
|
||||||
services.add( service );
|
services.add( service );
|
||||||
|
@ -254,4 +236,62 @@ public class ClassLoaderServiceImpl implements ClassLoaderService {
|
||||||
|
|
||||||
return services;
|
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