PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [JAVA] Problem beim dynamisches Laden von Klassen aus *.jar Dateien


PH4Real
2004-09-03, 19:40:56
So, ich habe folgendes Problem und bisher konnte weder Google noch irgendwelche Leute im IRC wirklich richtig helfen:

Ich möchte gerne eine Plugin Umgebung erstellen. Dazu gibt es den Ordner /plugins. In diesem lagern die *.jar Dateien, von denen jede *.jar Datei ein Plugin darstellt.

Jetzt habe ich zum Beispiel das Plugin "MyTestPlugin.jar" mit den Klassen "MyTestPlugin.class" und "TestClass.class".

Mittels Classloader kann ich die Klasse "MyTestPlugin" instantieren und benutzen. Wenn ich nun aber in "MyTestPlugin" auf "TestClass" zugreife, gibt es einen Fehler, da er "TestClass" nicht findet... :(

Meine Frage ist also: Wie kann ich "TestClass" so laden, dass anschliessend die dynamisch geladene Klasse "MyTestPlugin" sie findet?

Vielen Dank schonmal im Voraus!

HellHorse
2004-09-03, 22:31:12
Ich nehme mal an MyTestPlugin.jar noch nicht im CLASSPATH, denn sonst gäbe es wohl keine Probleme.

Probier mal folgendes:

public static void main(String[] args) throws Exception {
URL url = (new File("C:\\pfad\\zu\\MyTestPlugin.jar")).toURL();
ClassLoader loader = URLClassLoader.newInstance(new URL[]{url});
Class<?> clazz = loader.loadClass("paket.subpaket.MyTestPlugin");
String[] sa = new String[]{};
Method m = clazz.getMethod("main", new Class[]{sa.getClass()});
m.invoke(clazz.newInstance(), new Object[]{new String[]{"foo"}});
}

Das ruft die main Methode mit dem beliebten Paramter "foo" der Klasse paket.subpaket.MyTestPlugin auf. Haut so nur hin wenn paket.subpaket.MyTestPlugin einen Default Konstruktor hat.
Ich habe es bei mir mit einer Anwendung ausprobiert und es haut hin. Und ja, die Anwendung braucht dutzende andere Klassen.

Falls das bei dir nicht läuft, würde ich mal überprüfen, ob das JAR auch koscher ist. Das heisst es testweise mal dem CLASSPATH hinzufügen.

PH4Real
2004-09-04, 03:06:44
JUHUUUUU :) Es funktioniert! Danke!!... Du hast meinen Tag ähh... Nacht gerettet!

Habe bestimmt dutzende Threads durchwältzt, aber keiner wußte eine Antwort beziehungsweise hatte eine Lösung aus 5 Zeilen parat. Hatte schon angefangen meinen eigenen ClassLoader zu bauen und es hatte dann damit auch irgendwie funktioniert.

Aber jetzt nehme ich doch lieber deine Lösung, da sie mir doch um einiges sauberer erscheint =).

EDIT: Mittlerweile habe ich die Lösung so erweitert, dass jedes Plugin eine XML Desktriptor Datei mit zum Beispiel der Einstiegsklasse besitzt. Durch gemeinsame Interfaces muss ich auch nicht mehr die Methoden mittles Reflection suchen. =)

HellHorse
2004-09-04, 14:34:52
Freut mich, dass ich helfen konnte.