Java 9 - динамически добавлять jar во время выполнения
У меня проблема с загрузчиком классов с Java 9.
Этот код работал с предыдущими версиями Java:
private static void addNewURL(URL u) throws IOException {
final Class[] newParameters = new Class[]{URL.class};
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class newClass = URLClassLoader.class;
try {
Method method = newClass.getDeclaredMethod("addNewURL", newParameters );
method.setAccessible(true);
method.invoke(urlClassLoader, new Object[]{u});
} catch (Throwable t) {
throw new IOException("Error, could not add URL to system classloader");
}
}
Из этой ветки я узнал, что это должно быть заменено чем-то вроде этого:
Class.forName(classpath, true, loader);
loader = URLClassLoader.newInstance(
new URL[]{u},
MyClass.class.getClassLoader()
MyClass
это класс, который я пытаюсь реализовать Class.forName()
метод в.
u = file:/C:/Users/SomeUser/Projects/MyTool/plugins/myNodes/myOwn-nodes-1.6.jar
String classpath = URLClassLoader.getSystemResource("plugins/myNodes/myOwn-nodes-1.6.jar").toString();
По какой-то причине - я действительно не могу понять, почему - я получаю ClassNotFoundException при запуске Class.forName(classpath, true, loader);
Кто-то знает, что я делаю не так?
1 ответ
Из документации Class.forName(String name, boolean initialize, ClassLoader loader)
:-
бросает
ClassNotFoundException
- если класс не может быть найден указанным загрузчиком классов
Также обратите внимание, что аргументы, используемые для API, включают имя класса, с помощью которого загрузчик классов возвращает объект класса.
Учитывая полное имя для класса или интерфейса (в том же формате, который возвращается getName), этот метод пытается найти, загрузить и связать класс или интерфейс.
В вашем примере кода это можно исправить следующим образом:
// Constructing a URL form the path to JAR
URL u = new URL("file:/C:/Users/SomeUser/Projects/MyTool/plugins/myNodes/myOwn-nodes-1.6.jar");
// Creating an instance of URLClassloader using the above URL and parent classloader
ClassLoader loader = URLClassLoader.newInstance(new URL[]{u}, MyClass.class.getClassLoader());
// Returns the class object
Class<?> yourMainClass = Class.forName("MainClassOfJar", true, loader);
где MainClassOfJar
в приведенном выше коде должен быть заменен основной класс JAR myOwn-node-1.6.jar.