Hi,
Ich habe eine Frage die ihr mir bestimmt beantworten könnt
Erstmal zu dem was ich machen will:
- 1 Hauptprogramm
- n Plugins
Ich möchte die Plugins dynamisch laden können + meine Klassen aus dem Plugin mit vollqualifizierten Namen ansprechen.
Unter "normalen" Windowsanwendungen kenn ich das so, dass man einfach eine dll austauscht und man hat eine andere Implementierung der dll, ohne das man das Programm neu compilieren muss.
d.h. konkret ich möchte mit meinen Klassen aus den Plugins arbeiten können, ohne sie in Eclipse als Library hinzufügen zu müssen und ohne einen Import machen zu müssen.
Also existiert eine jar, wird sie geladen und benutzt, wenn nicht, dann nicht.
Ich habe bisher folgende Idee:
Ich habe mehrere Plugin-Projekte, ein Hauptprojekt und ein "API-Projekt". Das Api-Projekt enthält nur Interfaces. Sowohl in den Plugins, als auch im Hauptprogramm hab ich das API-Projekt gelinkt damit ich eben eine gemeinsame "Schnittstelle" habe.
Ich beschreibe mal meinen bisherigen Ansatz:
Hauptprogramm (gekürzt) :
ITransactions ist das Interface, welches aus dem API Projekt kommt und von den Plugins + Hauptprogramm verwendet wird.
plugin1 (gekürzt) :
naja...nichts besonderes... 
Im Plugin habe ich jedoch noch einen META-INF Ordner (innerhalb des src Ordners). Dort liegt ein Ordner "services". Dort liegt eine Datei mit den Namen "de.api.ITransactions" mit dem Inhalt "de.plugin1.HelloFromPlugin1" -> Damit das Hauptprogramm weiß welche Klasse es jetzt konkret instanziieren soll.
API (der Vollständigkeithalber) :
Ok, ich denke jetzt habe ich alle Infors beisammen
(Das Hauptprogramm hat keinen import von einem plugin!)
Dann exportiere ich die Plugins mittels Eclipse in jar-Dateien genau an den Pfad wie im Hauptprogramm angegeben.
Das hier gepostete Plugin-System funktioniert auch. Ich bekomme von jedem Plugin die "Hello ..." Ausgabe. alles super dachte ich
Jetzt mein konkretes Problem:
In einem der Plugins nutze ich Librarys (.jar) von Drittanbietern. Im Plugin als Library eingebunden und mittels Imports werden die benutzt. Wenn ich jetzt das Plugin nutzen will, bekomme ich eine ClassNotFoundException im Hauptprogramm. Irgendwas was wie "Kann Klasse HelloFromPlugin1 nicht instanziiere: ClassNotFoundException, cannot load class KlasseEinesDrittanbieters".
Das eigentliche Problem habe ich verstanden, habe jedoch keine Lösung dafür
Scheinbar läd das Hauptprogramm die .class Datei aus dem plugin1.jar und will die imports auflösen, kennt aber selber die Drittanbieter-jars nicht.
Kann mir jemand helfen?
Ist mein Mechanismuss zu "kompliziert" und es geht viel einfacher?
gruß und danke!
P.S.:
Zum Hintergrund: Das Programm soll "Daten verarbeiter" und die Plugins sollen die Quellen abstrahieren. zb. ein Plugin für eine DB, ein Plugin für Datein, ein Plugin zu einer externen API (hier kommen Drittanbieterlibrarys ins Spiel
). Dem Hauptprogramm soll es aber egal sein wo die Daten herkommen. Falls jemand eine bestimme Quelle nicht nutzt, dann bekommt er auch das Plugin nicht geliefert und dann wär es ärgerlich wenn ich trotzdem das SDK mit ausliefern muss nur um das Hauptprogramm nichtmehr neucompilieren zu müssen.
Ich habe eine Frage die ihr mir bestimmt beantworten könnt
Erstmal zu dem was ich machen will:
- 1 Hauptprogramm
- n Plugins
Ich möchte die Plugins dynamisch laden können + meine Klassen aus dem Plugin mit vollqualifizierten Namen ansprechen.
Unter "normalen" Windowsanwendungen kenn ich das so, dass man einfach eine dll austauscht und man hat eine andere Implementierung der dll, ohne das man das Programm neu compilieren muss.
d.h. konkret ich möchte mit meinen Klassen aus den Plugins arbeiten können, ohne sie in Eclipse als Library hinzufügen zu müssen und ohne einen Import machen zu müssen.
Also existiert eine jar, wird sie geladen und benutzt, wenn nicht, dann nicht.
Ich habe bisher folgende Idee:
Ich habe mehrere Plugin-Projekte, ein Hauptprojekt und ein "API-Projekt". Das Api-Projekt enthält nur Interfaces. Sowohl in den Plugins, als auch im Hauptprogramm hab ich das API-Projekt gelinkt damit ich eben eine gemeinsame "Schnittstelle" habe.
Ich beschreibe mal meinen bisherigen Ansatz:
Hauptprogramm (gekürzt) :
Java:
import de.api.ITransactions;
public class Main {
public static void main(String[] args) throws MalformedURLException {
System.out.println("load jars...");
File plugin1 = new File("Pfad/zum/plugin1.jar");
File plugin1 = new File("Pfad/zum/plugin2.jar");
URL[] url = {plugin1.toURI().toURL(), plugin2.toURI().toURL()};
URLClassLoader ucl = new URLClassLoader(url);
final Iterator<ITransactions> iter = ServiceLoader.load(ITransactions.class, ucl).iterator();
System.out.println("load classes...");
while (iter.hasNext()) {
final ITransactions plugin = iter.next();
System.out.println("output...");
plugin.doSomething();
}
}
}
plugin1 (gekürzt) :
Java:
import de.api.ITransactions;
public class HelloFromPlugin1 implements ITransactions {
@Override
public void doSomething() {
System.out.println("Hello from Plugin1");
}
}
Im Plugin habe ich jedoch noch einen META-INF Ordner (innerhalb des src Ordners). Dort liegt ein Ordner "services". Dort liegt eine Datei mit den Namen "de.api.ITransactions" mit dem Inhalt "de.plugin1.HelloFromPlugin1" -> Damit das Hauptprogramm weiß welche Klasse es jetzt konkret instanziieren soll.
API (der Vollständigkeithalber) :
Java:
package de.api;
public interface ITransactions {
public void doSomething();
}
Ok, ich denke jetzt habe ich alle Infors beisammen
(Das Hauptprogramm hat keinen import von einem plugin!)
Dann exportiere ich die Plugins mittels Eclipse in jar-Dateien genau an den Pfad wie im Hauptprogramm angegeben.
Das hier gepostete Plugin-System funktioniert auch. Ich bekomme von jedem Plugin die "Hello ..." Ausgabe. alles super dachte ich
Jetzt mein konkretes Problem:
In einem der Plugins nutze ich Librarys (.jar) von Drittanbietern. Im Plugin als Library eingebunden und mittels Imports werden die benutzt. Wenn ich jetzt das Plugin nutzen will, bekomme ich eine ClassNotFoundException im Hauptprogramm. Irgendwas was wie "Kann Klasse HelloFromPlugin1 nicht instanziiere: ClassNotFoundException, cannot load class KlasseEinesDrittanbieters".
Das eigentliche Problem habe ich verstanden, habe jedoch keine Lösung dafür
Scheinbar läd das Hauptprogramm die .class Datei aus dem plugin1.jar und will die imports auflösen, kennt aber selber die Drittanbieter-jars nicht.
Kann mir jemand helfen?
Ist mein Mechanismuss zu "kompliziert" und es geht viel einfacher?
gruß und danke!
P.S.:
Zum Hintergrund: Das Programm soll "Daten verarbeiter" und die Plugins sollen die Quellen abstrahieren. zb. ein Plugin für eine DB, ein Plugin für Datein, ein Plugin zu einer externen API (hier kommen Drittanbieterlibrarys ins Spiel