
name.remal.reflection.ExtendedURLClassLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of common Show documentation
Show all versions of common Show documentation
Java & Kotlin tools: common
The newest version!
package name.remal.reflection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import static name.remal.reflection.ExtendedURLClassLoader.LoadingOrder.*;
public class ExtendedURLClassLoader extends URLClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
public enum LoadingOrder {
PARENT_FIRST, THIS_FIRST, PARENT_ONLY, THIS_ONLY;
}
@FunctionalInterface
public interface LoadingOrderFactory {
@Nonnull
LoadingOrder getLoadingOrder(@Nonnull String className);
}
@Nonnull
private final LoadingOrderFactory loadingOrderFactory;
public ExtendedURLClassLoader(@Nonnull LoadingOrderFactory loadingOrderFactory, @Nonnull URL[] urls, @Nullable ClassLoader parent) {
super(urls, null != parent ? parent : getSystemClassLoader());
this.loadingOrderFactory = loadingOrderFactory;
}
public ExtendedURLClassLoader(@Nonnull LoadingOrder loadingOrder, @Nonnull URL[] urls, @Nullable ClassLoader parent) {
this(__ -> loadingOrder, urls, parent);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrderFactory loadingOrderFactory, @Nonnull Iterable urls, @Nullable ClassLoader parent) {
this(loadingOrderFactory, iterableUrlsToArray(urls), parent);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrder loadingOrder, @Nonnull Iterable urls, @Nullable ClassLoader parent) {
this(__ -> loadingOrder, urls, parent);
}
public ExtendedURLClassLoader(@Nonnull URL[] urls, @Nullable ClassLoader parent) {
this(PARENT_FIRST, urls, parent);
}
public ExtendedURLClassLoader(@Nonnull Iterable urls, @Nullable ClassLoader parent) {
this(PARENT_FIRST, urls, parent);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrderFactory loadingOrderFactory, @Nonnull URL[] urls) {
this(loadingOrderFactory, urls, null);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrder loadingOrder, @Nonnull URL[] urls) {
this(loadingOrder, urls, null);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrderFactory loadingOrderFactory, @Nonnull Iterable urls) {
this(loadingOrderFactory, urls, null);
}
public ExtendedURLClassLoader(@Nonnull LoadingOrder loadingOrder, @Nonnull Iterable urls) {
this(loadingOrder, urls, null);
}
public ExtendedURLClassLoader(@Nonnull URL[] urls) {
this(urls, null);
}
public ExtendedURLClassLoader(@Nonnull Iterable urls) {
this(urls, null);
}
@Nonnull
@Override
public Class> loadClass(@Nonnull String name) throws ClassNotFoundException {
return loadClass(name, false);
}
@Nonnull
@Override
protected Class> loadClass(@Nonnull String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class> loadedClass = findLoadedClass(name);
if (null == loadedClass) loadedClass = findSystemClassOrNull(name);
if (null == loadedClass) {
LoadingOrder loadingOrder = loadingOrderFactory.getLoadingOrder(name);
if (PARENT_FIRST == loadingOrder) {
loadedClass = findParentClassOrNull(name);
if (null == loadedClass) loadedClass = findClassOrNull(name);
} else if (THIS_FIRST == loadingOrder) {
loadedClass = findClassOrNull(name);
if (null == loadedClass) loadedClass = findParentClassOrNull(name);
} else if (PARENT_ONLY == loadingOrder) {
loadedClass = findParentClassOrNull(name);
} else if (THIS_ONLY == loadingOrder) {
loadedClass = findClassOrNull(name);
} else {
throw new IllegalStateException("Unsupported " + LoadingOrder.class.getSimpleName() + ": " + loadingOrder);
}
}
if (null == loadedClass) throw new ClassNotFoundException(name);
if (resolve) resolveClass(loadedClass);
return loadedClass;
}
}
@Nullable
protected Class> findSystemClassOrNull(@Nonnull String className) {
try {
return findSystemClass(className);
} catch (ClassNotFoundException e) {
return null;
}
}
@Nullable
protected Class> findClassOrNull(@Nonnull String className) {
try {
Class> loadedClass = findClass(className);
return loadedClass;
} catch (ClassNotFoundException e) {
return null;
}
}
@Nullable
protected Class> findParentClassOrNull(@Nonnull String className) {
ClassLoader parent = getParent();
if (null == parent) return null;
try {
Class> loadedClass = parent.loadClass(className);
return loadedClass;
} catch (ClassNotFoundException e) {
return null;
}
}
@Nonnull
private static URL[] iterableUrlsToArray(@Nonnull Iterable urls) {
if (urls instanceof List) return ((List) urls).toArray(new URL[0]);
List list = new ArrayList<>();
for (URL url : urls) list.add(url);
return list.toArray(new URL[0]);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy