Java 11-Problem beim Hinzufügen von Abhängigkeits-JARs zur LaufzeitJava

Java-Forum
Anonymous
 Java 11-Problem beim Hinzufügen von Abhängigkeits-JARs zur Laufzeit

Post by Anonymous »

Bei der Migration von Java 8 auf Java 11 wurde die folgende Fehlermeldung angezeigt:

Code: Select all

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')
Code, der den Fehler ausgelöst hat:

Code: Select all

URLClassLoader urlClassLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader();
...
//URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
...
getMethod().invoke(urlClassLoader, new Object[] { url });
Der obige Fehler wurde beim Laden von JAR-Dateien durch Erstellen eines ClassLoader gemäß diesem Link behoben:
Java 9, Kompatibilitätsproblem mit ClassLoader.getSystemClassLoader
Hier ist der Code:

Code: Select all

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());
}
}
Die Gläser wurden geladen mit:

Code: Select all

urlClassLoader.addURL(url);
Führen Sie das Glas aus mit

Code: Select all

-Djava.system.class.loader=com.ltchie.util.DynamicClassLoader
Aber das zur Kompilierungszeit hinzugefügte Dienstprogramm jar (jpf.jar – Java-Plugin-Framework) konnte die Klasse im dynamisch geladenen jar zur Laufzeit nicht finden und bekam eine ClassNotFoundException.
Code:

Code: Select all

Plugin plugin = pluginManager.getPlugin(pluginDescriptor.getId());
Fehler:

Code: Select all

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
Wenn ich dieses Glas zum Manifest meines Glases hinzufüge, funktioniert es. Aber ich muss zur Laufzeit laden, da diese Java-Befehlszeilenanwendung auf JPF basiert und es viele JARs gibt, die wir laden müssen, wenn wir die Anwendungs-JAR ausführen, die JPF verwendet.
Bei der weiteren Überprüfung ist mir aufgefallen, dass sich die PluginManager-Klasse in einem anderen Klassenlader befindet:

Code: Select all

16:57:14,000 INFO  [AppApplication] ############ pluginManager.getPlugin: jdk.internal.loader.ClassLoaders$AppClassLoader@799f7e29
Diese PluginManager-Instanz stammt aus der übergeordneten Klasse, die in jpf.jar verfügbar ist und in der JAR-Abhängigkeit zur Kompilierungszeit meines Anwendungs-JAR-Manifests definiert ist. Meine Anwendung läuft also mit dem Klassenlader DynamicClassLoader und lädt Laufzeit-JARs hinein. Aber das im Manifest hinzugefügte Abhängigkeits-JAR verwendet den Standard-AppClassLoader, was dazu führt, dass meine Klasse nicht gefunden werden kann.
Jeder, bitte schlagen Sie eine Lösung vor.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post