Ich versuche, ein Plugin-System für meine Anwendung zu implementieren, dessen Code meine Plugin-Klasse erweitert, um benutzerdefinierte Funktionen zu definieren.Wie .class aus dem Arbeitsverzeichnis zur Laufzeit von jar laden?
Dieser Code eine Klasse aus einem Glas zu laden, im selben Verzeichnis wie die .jar der Anwendung funktioniert gut:
if(pluginName.endsWith(".jar"))
{
JarFile jarFile = new JarFile(pluginName);
Enumeration jarComponents = jarFile.entries();
while (jarComponents.hasMoreElements())
{
JarEntry entry = (JarEntry) jarComponents.nextElement();
if(entry.getName().endsWith(".class"))
{
className = entry.getName();
}
}
File file = new File(System.getProperty("user.dir")+"/"+pluginName);
URLClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});
Class newClass = Class.forName(className.replace(".class", ""), true, loader);
newPlugin = (Plugin) newClass.newInstance();
}
in der richtigen Antwort führt aus:
benpalmer$ java -jar assignment.jar test_subproject.jar
- INFO: Add new plugin: source.com
Das Problem ist, ich möchte auch dem Benutzer die Option zur Verfügung stellen, eine .class-Datei stattdessen, da das ist realistisch alles, was in einem. Jar für die Zwecke meines Plugin-System gepackt ist.
else if(pluginName.endsWith(".class"))
{
File file = new File(System.getProperty("user.dir")+"/"+pluginName);
URLClassLoader loader = new URLClassLoader(new URL[]{file.toURI().toURL()});
Class newClass = Class.forName(className.replace(".class", ""), true, loader);
newPlugin = (Plugin) newClass.newInstance();
}
... exception handling
, die in den folgenden Ergebnissen:
benpalmer$ java -jar assignment.jar TestPlugin.class
SEVERE: Error: Plugin class not found. Class name:
java.lang.ClassNotFoundException:
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at newsfeed.model.Plugin.loadClassFromJarFile(Plugin.java:144)
at newsfeed.controller.NFWindowController.initPlugins(NFWindowController.java:81)
at newsfeed.controller.NewsFeed$1.run(NewsFeed.java:20)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
ich den obigen Code und viele Variationen von Pfadnamen versucht haben/andere Optionen, aber ClassNotFoundException jedes Mal bekommen. Hatte ursprünglich Probleme beim Laden der Jars, aber mit dem voll qualifizierten Pfad behoben, dass ich jetzt die Klassen nicht laden kann.
Irgendwelche Ideen? :)
sollten Sie wirklich verwenden [ServiceLoader] (https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html) dafür. – VGR