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.

Другие вопросы по тегам