2017-02-03 9 views
7

Grundsätzlich habe ich Java ein System, das eine Reihe von "Plugin" -Skripten mit Javascript entweder über Rhino oder Nashorn, je nachdem, was JRE der Benutzer installiert hat.Hinzufügen und entfernen Jar-Dateien und Klassen von innen JavaScript (Rhino/Nashorn)

Ich habe auch ein System innerhalb der Java-Umgebung, die das Plug-In von zusätzlichen .JAR-Dateien zur Laufzeit ermöglicht.

Das ist alles gut und dandy. Ich bin jedoch auf eine Situation gestoßen, in der ich etwas anderes möchte: Ich möchte eine .JAR-Datei von innerhalb der Rhino/Nashorn-Engine-Instanz in den ClassPath laden, damit die Klassen für diese Instanz (und nur für diese Instanz) verfügbar sind) und dann entfernen Sie sie, wenn der Motor ausgeführt wird.

Ich weiß, dass ich meine vorhandene Java-Routine leicht aufrufen kann, um die URL der .JAR-Datei mit JavaScript zu laden, aber die Klassen sind dann dauerhaft installiert und ich kann sie nicht loswerden.

Das Problem ergibt sich im Grunde aus der Tatsache, dass ein Benutzer mehrere Plugins mit verschiedenen Versionen der gleichen .JAR-Datei (es wird von einer dritten Partei zur Verfügung gestellt und für mehrere verschiedene Plugins auf unterschiedliche Weise verwendet) haben kann, und ich brauche die Plugins in der Lage sein, die richtige zu laden und sie anschließend zu entfernen.

Meine vorhandenen URL-Loader ist:

public static void addURL(URL u) { 
    final Class[] parameters = new Class[]{URL.class}; 
    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
    Class sysclass = URLClassLoader.class; 

    try { 
     Method method = sysclass.getDeclaredMethod("addURL", parameters); 
     method.setAccessible(true); 
     method.invoke(sysloader, new Object[]{u}); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
} 

Nun weiß ich nicht wirklich viel Ahnung haben, wie das funktioniert - ich bin nicht eine Macht Java-Programmierer (ich C/C++ in erster Linie). Ich weiß, dass Sie eine URL aus dem URLClassLoader nicht "entladen" können, also frage ich das nicht. Am besten wäre es, wenn ich die JAR-Datei einem "temporären" URLClassLoader hinzufügen könnte, den ich dann am Ende der Ausführung ablege. Oder ich kann die Klassen einfach direkt in die Skript-Engine und nicht in den Java ClassPath laden.

Wenn es etwas ist, das ich gerade von JavaScript direkt aufrufen könnte, wäre das großartig, aber ich habe nichts dagegen, einige Java-Methoden zu implementieren, wenn nötig, oder sogar die Scripting-Engine zu erweitern.

Antwort

5

Um die pluginspezifischen Klassen zu isolieren, müssen Sie möglicherweise eine separate (benutzerdefinierte) Klassenladerinstanz erstellen und an die Java-Skript-Engine übergeben. Jede Klasse, die vom bestimmten Klassenlader geladen wird, ist nur für die jeweilige Java-Skript-Engine sichtbar.

Ich habe this answer gefunden, die den Klassenlader im Zusammenhang mit ScriptEngine beschreiben.

Ich hoffe, dass dies Ihnen hilft, in die richtige Richtung voranzukommen.

Verwandte Themen