Пользовательский загрузчик классов Java не используется для загрузки зависимостей?
мы пытались настроить собственный загрузчик классов, который перехватывает классы, чтобы распечатать, какие классы загружаются в приложение. Загрузчик классов выглядит так
public class MyClassLoader extends ClassLoader {
@Override
public Class loadClass(String name) throws ClassNotFoundException {
System.out.println("Loading: " + name);
return super.loadClass(name);
}
}
Он просто выдает имя всех классов, которые загружает. Тем не менее, когда я пытаюсь запустить какой-то код,
import org.python.util.PythonInterpreter;
public class Scripts {
public String main(){
PythonInterpreter p = new PythonInterpreter();
p.exec("print 'Python ' + open('.gitignore').read()");
return "Success! Nothing broke";
}
}
с помощью
MyClassLoader bcl = new MyClassLoader();
Class c = bcl.loadClass("Scripts");
Method m = c.getMethod("main");
String result = (String) m.invoke(c.getConstructor().newInstance());
это распечатывает
Loading: Scripts
Loading: java.lang.Object
Loading: java.lang.String
Loading: org.python.util.PythonInterpreter
Python build/
.idea/*
*.iml
RESULT: Success! Nothing broke
Что кажется довольно странным.org.python.util.PythonInterpreter
не простой класс, и это зависит от целого ряда других классов вorg.python.util
пакет. Эти классы явно загружаются, дляexec
d Python-код умеет делать вещи и читать мой файл. Однако по какой-то причине эти классы не загружаются загрузчиком классов, который загрузил.PythonInterpreter
Это почему? У меня сложилось впечатление, что загрузчик классов раньше загружал классC
будет использоваться для загрузки всех других классов, необходимыхC
, но это'Здесь явно не происходит. Это предположение ошибочно? Если это так, как я могу настроить его так, чтобы все переходные зависимостиC
загружаются моим загрузчиком классов?
РЕДАКТИРОВАТЬ:
Некоторые эксперименты с использованиемURLClassLoader
, который был предложен. Я изменил делегирование в:loadClass()
try{
byte[] output = IOUtils.toByteArray(this.getResourceAsStream(name));
return instrument(defineClass(name, output, 0, output.length));
}catch(Exception e){
return instrument(super.loadClass(name));
}
а также сделал MyClassLoader подклассом URLClassLoader вместо простого ClassLoader, захватывая URL через:
super(((URLClassLoader)ClassLoader.getSystemClassLoader()).getURLs());
Но это неКажется, это не так. Особенно,getResourceAsStream()
отбрасывает ноль обратно на меня для всех классов, которые яЯ запрашиваю даже несистемные классы, подобные Jython lib.