package org.opensha2.etc; import java.net.URL; import java.net.URLClassLoader; import java.util.List; class ParentLastURLClassLoader extends ClassLoader { private ChildURLClassLoader childClassLoader; ParentLastURLClassLoader(List<URL> classpath) { super(Thread.currentThread().getContextClassLoader()); URL[] urls = classpath.toArray(new URL[classpath.size()]); childClassLoader = new ChildURLClassLoader(urls, new FindClassClassLoader(this.getParent())); } /* Class permits calls to protected Classloader.findClass(). */ private static class FindClassClassLoader extends ClassLoader { public FindClassClassLoader(ClassLoader parent) { super(parent); } @Override public Class<?> findClass(String name) throws ClassNotFoundException { return super.findClass(name); } } /* * This class delegates (child then parent) the protected findClass() method * of a URLClassLoader. */ private static class ChildURLClassLoader extends URLClassLoader { private FindClassClassLoader realParent; public ChildURLClassLoader(URL[] urls, FindClassClassLoader realParent) { super(urls, null); this.realParent = realParent; } @Override public Class<?> findClass(String name) throws ClassNotFoundException { try { // try to use the URLClassLoader findClass return super.findClass(name); } catch (ClassNotFoundException e) { // otherwise ask the real parent classloader to load the class return realParent.loadClass(name); } } } @Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { try { // try to find a class inside the child classloader return childClassLoader.findClass(name); } catch (ClassNotFoundException e) { // then try the parent return super.loadClass(name, resolve); } } }