For some reasons, I need a child-first ClassLoader
. Such ClassLoader
doesn't exist in the JDK, so I'm writing it. Since this is a key component of my use case, I'd like it to be heavily tested. To ensure it's not changed without breaking the behavior, I want to be extremely thorough and test all that's testable automatically.
So how can I test it? How should I make my basic unit test? I'm kind of stuck as to where to start (especially since there's at least one super
call in each method) and I'm looking for some guidelines to start.
My main idea is the following. Is there anything wrong with it?
/src/main/resources/parent.jar
child.jar
The file parent.jar
contains a class com.example.Example
which is a basic Supplier
returning "parent"
. The file child.jar
contains a class com.example.Example
which is a basic Supplier
returning "child"
.
I'd be creating a standard URLClassLoader
for parent.jar
, and I'd use my custom ClassLoader
to load child.jar
. Then I'd load the class com.example.Example
and check that it's actually returning "child"
instead of "parent"
.
More complex test cases are thought about, but I just need a confirmation to start: is this enough for the basic test? Is this really what I should be testing in my unit tests? If not, what is?
I'm quite sure the code is not needed for this, but in case you're curious or whatever, here's it.
import java.io.*;
import java.net.*;
import java.util.*;
class ChildFirstClassLoader extends URLClassLoader {
ChildFirstClassLoader(ClassLoader parent) {
super(new URL[0], parent);
}
@Override
// Make this method available in this package.
protected void addURL(URL url) {
super.addURL(url);
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
c = findClass(name);
} catch (ClassNotFoundException ignore) {
c = super.loadClass(name, resolve);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
@Override
public URL getResource(String name) {
URL url = findResource(name);
if (url == null) {
url = super.getResource(name);
}
return url;
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
List<URL> urls = new ArrayList<>();
urls.addAll(Collections.list(findResources(name)));
urls.addAll(Collections.list(super.getResources(name)));
return Collections.enumeration(urls);
}
}