Проблема Java 11 с добавлением jar-файлов зависимостей во время выполненияJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Проблема Java 11 с добавлением jar-файлов зависимостей во время выполнения

Сообщение Anonymous »

При переходе с Java 8 на Java 11 возникла следующая ошибка:

Код: Выделить всё

Caused by: java.lang.ClassCastException: class jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to class java.net.URLClassLoader (jdk.internal.loader.ClassLoaders$AppClassLoader and java.net.URLClassLoader are in module java.base of loader 'bootstrap')
Код, вызвавший ошибку:

Код: Выделить всё

URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
...
//URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
...
getMethod().invoke(urlClassLoader, new Object[] { url });
Вышеуказанная ошибка исправлена ​​при загрузке jar-файлов путем создания ClassLoader по этой ссылке:
Java 9, проблема совместимости с ClassLoader.getSystemClassLoader
Вот код:

Код: Выделить всё

public class DynamicClassLoader extends URLClassLoader {

public DynamicClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}

public void addURL(URL url) {
super.addURL(url);
}

public DynamicClassLoader(String name, ClassLoader parent) {
super(name, new URL[0], parent);
}

/*
* Required when this classloader is used as the system classloader
*/
public DynamicClassLoader(ClassLoader parent) {
this("classpath", parent);
}

public DynamicClassLoader() {
this(Thread.currentThread().getContextClassLoader());
}

public static DynamicClassLoader findAncestor(ClassLoader cl) {
do {

if (cl instanceof DynamicClassLoader)
return (DynamicClassLoader) cl;

cl = cl.getParent();
} while (cl != null);

return null;
}

/*
*  Required for Java Agents when this classloader is used as the system classloader
*/
@SuppressWarnings("unused")
private void appendToClassPathForInstrumentation(String jarfile) throws IOException {
addURL(Paths.get(jarfile).toRealPath().toUri().toURL());
}
Загрузили банки с помощью:

Код: Выделить всё

urlClassLoader.addURL(url);
Запустите jar с помощью

Код: Выделить всё

-Djava.system.class.loader=com.ltchie.util.DynamicClassLoader
Но служебный jar (jpf.jar — платформа плагинов Java), добавленный во время компиляции, не смог найти класс в динамически загружаемом jar во время выполнения и получил исключение ClassNotFoundException.
Код:

Код: Выделить всё

Plugin plugin = pluginManager.getPlugin(pluginDescriptor.getId());
Ошибка:

Код: Выделить всё

15:25:54,015 INFO  [AppApplication] >>>>>>>> loadLibraries() - ClassLoader: com.app.util.DynamicClassLoader@2f67b837  ...

java.lang.NoClassDefFoundError: org/app/plugin/AppCommandPlugin
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:550)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
at org.java.plugin.standard.StandardPluginClassLoader.loadLocalClass(StandardPluginClassLoader.java:395)
at org.java.plugin.standard.StandardPluginClassLoader.loadPluginClass(StandardPluginClassLoader.java:464)
at org.java.plugin.standard.StandardPluginClassLoader.loadClass(StandardPluginClassLoader.java:372)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at org.java.plugin.standard.StandardPluginLifecycleHandler.createPluginInstance(StandardPluginLifecycleHandler.java:113)
at org.java.plugin.standard.StandardPluginManager.activatePlugin(StandardPluginManager.java:402)
at org.java.plugin.standard.StandardPluginManager.getPlugin(StandardPluginManager.java:217)
at org.app.command.AppApplication.getPlugin(AppApplication.java:253)
at org.app.command.AppApplication.execute(AppApplication.java:228)
at org.app.command.AppApplication.execute(AppApplication.java:221)
at org.app.command.AppApplication.startApplication(AppApplication.java:113)
at org.java.plugin.boot.Boot.boot(Boot.java:346)
at org.java.plugin.boot.Boot.main(Boot.java:243)
at org.app.plugin.boot.TPFBoot.main(TPFBoot.java:112)
Caused by: java.lang.ClassNotFoundException: org.app.plugin.AppCommandPlugin
at org.java.plugin.standard.StandardPluginClassLoader.loadClass(StandardPluginClassLoader.java:378)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 22 more
Когда я добавляю этот jar в манифест своего jar, он работает. Но мне нужно загружать во время выполнения, так как это Java-приложение командной строки основано на JPF, и есть много jar-файлов, которые нам нужно загрузить, когда мы запускаем jar-файл приложения, который использует JPF.
При дальнейшей проверке заметил, что класс плагинаManager имеет другой загрузчик классов:

Код: Выделить всё

16:57:14,000 INFO  [AppApplication] ############ pluginManager.getPlugin: jdk.internal.loader.ClassLoaders$AppClassLoader@799f7e29
Этот экземпляр плагинаManager принадлежит родительскому классу, доступному в jpf.jar, который определен в зависимости jar во время компиляции моего манифеста jar приложения. Итак, мое приложение работает с загрузчиком классов DynamicClassLoader и загружает в него jar-файлы времени выполнения. Но jar-файл зависимостей, добавленный в манифест, использует AppClassLoader по умолчанию, из-за чего не удается найти мой класс.
Кто-нибудь, предложите решение.

Подробнее здесь: https://stackoverflow.com/questions/683 ... at-runtime
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»