Класс загрузки NoClassDefFoundError с помощью URLClassLoader

Мы пытаемся поддерживать плагины для нашего продукта, и я использую отражение для загрузки класса из банки.

Я создаю URL-адрес ClassLoader и добавляю все банки зависимостей в качестве URL-адресов.

Я использую этот ClassLaoder для загрузки основного класса плагина.

Я получаю экземпляр класса и ссылку на метод (метод run()).

Когда я вызываю метод, я получаю это исключение:

java.lang.NoClassDefFoundError: не удалось инициализировать класс org.apache.logging.log4j.util.PropertiesUtil

Этот класс находится в файле log4j-api-2.10.0.jar, который включен в путь к классам ClassLoader.

Я вижу URL-адрес в загрузчике классов в отладке, поэтому я знаю, что на него правильно ссылаются.

Иногда я получаю другую ошибку, говоря, что он не может инициализировать один из моих классов, но этот класс не является чем-то особенным, никакой статикой или чем-то еще.

Основной класс, загружаемый отражением, вызывает второй класс, использующий Log4j 2.

Когда метод run() основного класса пытается создать экземпляр второго класса, возникает эта проблема.

В любом классе нет ничего статического, кроме Logger.

В отладчике я вижу из ссылки на метод, что класс действительно был загружен с помощью созданного нами URL ClassLoader.

Этот код работает уже десять лет, и единственное, что мы изменили, — это обновление до Log4j 2 в плагине. Класс, выполняющий загрузку отражающего плагина, является обычным классом в пути к классам приложения.

Любая помощь будет принята с благодарностью.

Используя предложение Drizzle, я получаю:

Exception in thread "ServerStatus:update_timer:" java.lang.ExceptionInInitializerErrorException in thread "ServerStatus:update_timer:" java.lang.ExceptionInInitializerError
    at java.lang.Class.forName0(Native Method)  at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)  at java.lang.Class.forName(Unknown Source)
    at ...
    at java.lang.Thread.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: java.util.Vector cannot be cast to java.lang.StringCaused by: java.lang.ClassCastException: java.util.Vector cannot be cast to java.lang.String
    at org.apache.logging.log4j.util.SystemPropertiesPropertySource.forEach(SystemPropertiesPropertySource.java:39)
    at org.apache.logging.log4j.util.SystemPropertiesPropertySource.forEach(SystemPropertiesPropertySource.java:39)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.reload(PropertiesUtil.java:330) at org.apache.logging.log4j.util.PropertiesUtil$Environment.reload(PropertiesUtil.java:330)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:322) at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:322)
    at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:310) at org.apache.logging.log4j.util.PropertiesUtil$Environment.<init>(PropertiesUtil.java:310)
    at org.apache.logging.log4j.util.PropertiesUtil.<init>(PropertiesUtil.java:69)  at org.apache.logging.log4j.util.PropertiesUtil.<init>(PropertiesUtil.java:69)
    at org.apache.logging.log4j.util.PropertiesUtil.<clinit>(PropertiesUtil.java:49)    at org.apache.logging.log4j.util.PropertiesUtil.<clinit>(PropertiesUtil.java:49)

Обновление: Log4j 2 версии 2.10.x и более поздних версий содержит ошибки. Загрузка классов рефлексивно выявляет ошибки. При переключении обратно на 2.8.2 указанное выше исключение исчезает. Однако теперь я все еще получаю ClassNotFound для одного из своих классов.


person K. Taylor    schedule 29.06.2018    source источник
comment
Как вы создаете URLClassLoader?   -  person Johannes Kuhn    schedule 29.06.2018
comment
новый URLClassLoader(getPluginClassPath(url), Thread.currentThread().getContextClassLoader()); getPluginClassPath() просто создает все URL-адреса для зависимостей   -  person K. Taylor    schedule 29.06.2018
comment
Как вы можете видеть выше, есть проблема с Log4j 2. Что касается сборки env, это не поможет. Он достаточно сложный, с использованием множества технологий. Это не проблема сборки.   -  person K. Taylor    schedule 29.06.2018


Ответы (2)


Резервное копирование Log4j до версии 2.8.2 решило проблему. Это ошибка в Log4j. Спасибо за помощь. Человек, которого было трудно найти.

person K. Taylor    schedule 29.06.2018

это может быть полезно для решения java.lang.NoClassDefFoundError

try {
    Class.forName("org.apache.logging.log4j.util.PropertiesUtil");
} catch (Exception e) {
    e.printStackTrace();
}
person Drizzle    schedule 29.06.2018
comment
Хорошая идея попробую - person K. Taylor; 29.06.2018
comment
Я не уверен, что это будет полезно - OP, скорее всего, столкнется с NoClassDefFoundError при выполнении вашего кода. Проблема ОП заключается в том, что их путь к классам не содержит зависимости, а @K.Taylor - пожалуйста, обновите вопрос, указав свою среду сборки (Maven, Gradle, обычный Eclipse и т. д.), и сообщество в целом будет лучше подготовлены, чтобы ответить на ваш вопрос. - person Dave; 29.06.2018
comment
Итак, почему этот ответ отклонен, разрешение предоставлено, учитывая, что необходимые библиотеки включены в приложение. - person Drizzle; 29.06.2018
comment
Без понятия. Я проголосовал за это. Я сделаю это снова, если он примет это. Собственно, именно это и показало ошибку в Log4j. - person K. Taylor; 29.06.2018