Aiun Geschrieben 13. Oktober 2005 Teilen Geschrieben 13. Oktober 2005 hi, ich arbeite z.Z. an einer Anwendung, die später vermutlich durch optionale Plugins erweitert wird. In dem Fall wird ein Plugin ein eigener JFrame-Dialog (und damit verbundene verarbeitungsklassen ) sein. Um ein Beispiel zu nennen (unrealistisch ich weis...aber der Sinn passt): der User kann über ein Plugin-Menü einen Taschenrechner-Dialog aufrufen. Ein anderer Plugin gibt ihm die Möglichkeit, Textbausteine vorzudefinieren die dann im Hauptprogramm eingefügt werden.... so etwas in der Art. Die Frage ist, wie mache ich das ? Eine Idee war, das eine Konfig-Datei alle Plugins auflistet. Der eigentliche Plugin-Code wird dann jeweils als Jar-File hinzugefügt. In der Anwendung lese ich die Konfig-Datei aus......aber was dann ? kann ich ein Jar-File zur Laufzeit hinzuladen ? wenn ich die Klassen des Plugins dann "zur verfügung" habe, wie kann ich dynamisch entscheiden, von Welcher klasse ich eine Instanz bilden möchte ? (sagen wir alle Plugins erben von Oberklasse Plugin, oder erfüllen das Interface Plugin) In PHP habe ich das mal mit einer art $var = new $klassenname(); gemacht....aber ich bezweifle das es so einfach in Java geht... ich hoffe ihr könnt weiterhelfen, danke Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
_Arvid_ Geschrieben 13. Oktober 2005 Teilen Geschrieben 13. Oktober 2005 kann ich ein Jar-File zur Laufzeit hinzuladen ? ... wie kann ich dynamisch entscheiden, von Welcher klasse ich eine Instanz bilden möchte? Schau dir mal die Klasse ClassLoader an und suche vielleicht auch nach sowas wie JarLoader. Das dürfte dich ein wenig inspirieren, denke ich. http://www.google.de/search?q=java+jarloader+classloader EDIT Kleiner Nachtrag von mir... Weiß nicht, ob das Framework zu empfehlen ist, hab mich jetzt auch nicht großartig reingelesen. Aber versuche es mal mit JPF. Vielleicht ist das ja ganz gut.... Ansonsten suche bei namhaften Suchmaschinen auch nach soetwas wie "java plugin system" oder so. Da findet man unter Anderem das erwähnte JPF. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
nokri Geschrieben 13. Oktober 2005 Teilen Geschrieben 13. Oktober 2005 Ich würde hierzu eine zweite Sprache einbetten (Python?) und mich nur in Java um das Design und das OS-Interface (Dateihandling) kümmern. Den ganzen Rest in eben einer interpretierenden Sprache ausführen lassen. Der Vorteil: Modulares Programmieren Java-Programm kann sehr stabil gemacht werden! Nachteil: 2 Sprachen Funktionsupdates der einen, können zu Fehlern der anderen führen Du musst halt in Java die Fernsteuerung eines Interpreters beherrschen inkl. Fehlerhandling usw. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Aiun Geschrieben 13. Oktober 2005 Autor Teilen Geschrieben 13. Oktober 2005 hmm...weis nicht ob eine 2. Sprache das ist was ich suche. Das Problem bliebe das Selbe...wie lade ich denn die Plugins die da bereitgestellt werden ? die Haupt-Applikation hat keine Ahnung, was für Plugins da kommen könnten. (da es erstmal um das Prinzip geht ... später werden natürlich Rahmenbedingungen vorrausgesetzt) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
nokri Geschrieben 13. Oktober 2005 Teilen Geschrieben 13. Oktober 2005 dazu benutzt Du eine strukturierte Indexdatei, die von der Java-Anwendung gelesen und verarbeitet wird. Die einzelnen Plugins sollten so konzipiert sein, dass sie Teile dieses Indexes in die Verarbeitung mit einbeziehen (bestimmte Parameter für Interpreter?). Input-Output Parameter sollten ebenfalls deklariert werden können (welche Daten sollen übergeben werden, welche Daten sollen zurückgeliefert werden). Ich mache dies immer anhand von math. Beispielen: Für Formel a^2+b^2=c^2 brauchst Du min 2 Input-Paramter und der Output-Parmater stellt die fehlende Variable da, die zurückgeliefert wird. Wie das Programm nun den zurückliefernden Output berechnet, ist null und nichtig in Java Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
perdian Geschrieben 13. Oktober 2005 Teilen Geschrieben 13. Oktober 2005 Du hast das wichtigsten schon selber vorausgenommen - um das Laden deiner eigenen Plugin-Klassen wirst du nicht herumkommen, das heisst mit dem ClassLoader Konzept wirst du dich auf jeden Fall beschäftigen müssen. Der erste Schritt ist also erstmal herauszufinden welche Plugins überhaupt verfübar sind. Das geht entweder über eine Konfigurationsdatei, in der alle Plugins aufgelistet sind, oder über ein implizites Verzeichnis-Listing (jeder Unterverzeichnis in Verzeichnis X definiert ein Plugin. Diese Infos ziehst du in einen Plugin-Descriptor, der in etwa so aussehen könnte: public class PluginDescriptor { private File myPluginDirectory = null; /** * Sets the directory, in which the plugin files are located */ public void setPluginDirectory(File directory) { this.myPluginDirectory = directory; } /** * Gets the directory, in which the plugin files are located */ public File getPluginDirectory() { return this.myPluginDirectory; } } Damit hast du dann die Info was ist vorhanden. Jetzt gilt es die Frage wie komme ich an die Plugin-Logik zu beantworten. Ich finde da die Eclipse Variante immer noch am besten - in jedem Plugin Verzeichnis ist ein Descriptor vorhanden, der die zu ladende Plugin-Klasse angibt, also in etwa so etwas: <?xml version="1.0" encoding="ISO-8859-1" ?> <plugin> <plugin-class value="de.perdian.test.PluginTest" /> </plugin> Anhand dieser Infos können wir jetzt mit dem Plugin-Laden beginnen. Hierzu nehmen wir uns einen eigenen ClassLoader, aus dem wir die in der XML Datei definierte Klasse laden. Die implementiert das allgemeine Interface Plugin, das als Argument die Einstellungen des aktuellen Systems erhält und dann die eigentliche Logik ausführt. Dem ClassLoader selbst übergeben wir als zusätzlichen Classpath (zum System Classpath) alle Dateien, die im Plugin-Verzeichnis unterhalb eines Lib-Verzeichnisses liegen. Und schon sind wir fertig Implementierungsmäßig in etwa so: public class PluginLoader { public void loadPlugins(ApplicationEnvironment ae) { File pluginsDirectory = this.computePluginDirectory(); File[] pluginDirectories = pluginsDirectory.listFiles(); for(File pluginDirectory : pluginDirectories) { PluginDescriptor pluginDescriptor = new PluginDescriptor(); pluginDescriptor.setPluginDirectory(pluginDirectory); this.loadPlugin(pluginDescriptor, ae); } } protected void loadPlugin(PluginDescriptor pd, ApplicationEnvironment ae) { try { // Compute new classpath File libDirectory = new File(pd.getPluginDirectory(), "lib"); File libFiles[] = libDirectory.listFiles(); URL[] libURLs = new URL[libFiles.length); for(int i=0; i < libFiles.length; i++) { libURLs[i] = libFiles[i].toURL(); } // Compute plugin class name File xmlFile = new File(pd.getPluginDirectory(), "descriptor.xml"); Document xmlDocument = XmlTools.createDocument(xmlFile); Element pluginClassElement = XmlTools.getFirstFittingElement(xmlDocument, "plugin-class"); String pluginClassValue = pluginClassElement.getAttribute("value"); // Create ClassLoader, load plugin and execute ClassLoader pluginClassLoader = new URLClassLoader(libURLs, this.getClassLoader()); Class pluginClass = pluginClassLoader.loadClass(pluginClassValue); Plugin pluginInstance = (Plugin)pluginClass.newInstance(); pluginInstance.executePlugin(ae); } catch(Exception e) { throw new RuntimeException("Cannot load Plugin"); } } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Aiun Geschrieben 13. Oktober 2005 Autor Teilen Geschrieben 13. Oktober 2005 danke dir Perdi. Ich hatte noch keine Ahnung von Classloader unsw. hab mit dem Denkansatz von Ar-sch schon was gefunden und basteln können. Die Idee mit den XML & Co erweitert das ganze noch ... wunderbar also danke euch *so ein Oskar-verleihung-dankgelaber-aufsetzt* Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.