
com.github.edgar615.util.reflect.ClassLoaderChain Maven / Gradle / Ivy
The newest version!
package com.github.edgar615.util.reflect;
import com.github.edgar615.util.collection.CompoundEnumeration;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Chains multiple class loaders.
*
* @author [email protected]
*/
public class ClassLoaderChain extends ClassLoader {
public static final Logger log = LoggerFactory.getLogger(ClassLoaderChain.class.getName());
private final Collection classLoaders;
private ClassLoaderChain(Collection classLoaders) {
this.classLoaders = classLoaders;
}
/**
* Creates a chain of class loaders. Handles null
properly. This will create a new
* chain, even if there is only one classloader in the chain. The usage for this is that
* ResourceBundle caches resource per classloader.
*
* @return a class loader (never null
)
*/
public static ClassLoader createNewChain(ClassLoader... classLoaders) {
return createChain(Arrays.asList(classLoaders), true);
}
/**
* Creates a chain of class loaders. Handles null
properly.
*
* @return a class loader (never null
)
*/
public static ClassLoader createChain(ClassLoader... classLoaders) {
return createChain(Arrays.asList(classLoaders), false);
}
/**
* Creates a chain of class loaders. Handles null
properly.
*
* @return a class loader (never null
)
*/
public static ClassLoader createChain(List classLoaders) {
return createChain(classLoaders, false);
}
/**
* Creates a chain of class loaders. Handles null
properly.
*
* @param createNew whether to create new instance of classloaderchain even if there is only one
* loader
* @return a class loader (never null
)
*/
public static ClassLoader createChain(List classLoaders, Boolean createNew) {
List list = new ArrayList(classLoaders.size());
for (ClassLoader classLoader : classLoaders) {
// we skip null class loaders
if (classLoader == null) {
continue;
}
// we skip null class loaders
if (classLoader instanceof NullClassLoader) {
continue;
}
// we 'flatten' the chain... no need to have a chain of a chain...
if (classLoader instanceof ClassLoaderChain) {
ClassLoaderChain classLoaderChain = (ClassLoaderChain) classLoader;
list.addAll(classLoaderChain.classLoaders);
} else {
list.add(classLoader);
}
}
if (list.size() == 0) {
return NullClassLoader.instance();
}
// remove duplicates
ClassLoader previous = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
ClassLoader next = iter.next();
if (next.equals(previous)) {
iter.remove();
}
previous = next;
}
//TODO: create a new entry point, and keeping old behavior unchanged.
if (list.size() == 1 && !createNew) {
return list.get(0);
}
return new ClassLoaderChain(list);
}
@Override
public Class loadClass(String name) throws ClassNotFoundException {
Class clazz = null;
for (ClassLoader classLoader : classLoaders) {
try {
clazz = classLoader.loadClass(name);
return clazz;
} catch (ClassNotFoundException e) {
log.debug("class not found in " + classLoader + "... moving to next one");
}
}
throw new ClassNotFoundException(name);
}
@Override
public URL getResource(String name) {
URL url = null;
for (ClassLoader classLoader : classLoaders) {
url = classLoader.getResource(name);
if (url != null) {
return url;
}
}
return url;
}
@Override
@SuppressWarnings("unchecked")
public Enumeration getResources(String name) throws IOException {
Enumeration[] enums = new Enumeration[classLoaders.size()];
int i = 0;
for (ClassLoader classLoader : classLoaders) {
enums[i++] = classLoader.getResources(name);
}
return new CompoundEnumeration(enums);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy