Я пытаюсь сделать URLClassLoader, который ведет себя следующим образом:
-
Если запрашивается класс, имя которого входит в данный набор включений, загрузите его как обычно
-
В противном случае верните фиктивный класс
Я не могу заставить это работать. В приведенной ниже попытке я ожидаю, что SpecialClassLoader
успешно загрузит Test$Thing
. При этом я ожидаю, что он попытается загрузить Test$SuperThing
, и я ожидаю, что все будет в порядке с тем фактом, что вместо него загружен фиктивный класс Nothing
.
Однако что-то идет не так, и NoClassDefFoundError
бросается в поисках Test$SuperThing
.
Кто-нибудь знает, как это исправить?
public class Test {
private static class SuperThing {}
private static class Thing extends SuperThing {}
public static void main(String[] args) {
Set<String> inclusions = new HashSet<String>();
inclusions.add("Test$Thing"); // note Test$SuperThing is excluded
URLClassLoader cl = (URLClassLoader)
Thread.currentThread().getContextClassLoader();
SpecialClassLoader cll =
new SpecialClassLoader(cl.getURLs(), inclusions);
try {
cll.loadClass("Test$Thing"); // line 22 (see stacktrace below)
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private static class Nothing {}
private static final class SpecialClassLoader extends URLClassLoader {
private final Set<String> inclusions;
public SpecialClassLoader(URL[] urls, Set<String> inclusions) {
super(urls);
this.inclusions = inclusions;
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (inclusions.contains(name)) {
return findClass(name); // line 40 (see stacktrace below)
}
return Nothing.class;
}
}
}
РЕДАКТИРОВАТЬ: вот полученная мной трассировка стека (номера строк 22 и 40 указаны в листинге выше):
Exception in thread "main" java.lang.NoClassDefFoundError: Test$SuperThing
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at Test$SpecialClassLoader.loadClass(Test.java:40)
at Test.main(Test.java:22)