2Danke
ERLEDIGT
NEIN
NEIN
ANTWORTEN
14
14
ZUGRIFFE
554
554
EMPFEHLEN
-
Hi alle zusammen!
Ich habe ein Programm, welches ich gern per Plugin erweiterbar machen möchte. (ala Firefox,Eclipse oder so ähnlich)
Wie setze ich sowas um?
Weiß jemand wie man's macht oder hat jemand vllt. nen Link?
Danke schonnema!/* no comment */
-
20.04.10 12:43 #2
Geht ganz einfach. Ich definiere zuerst ein Interface oder eine abstrakte Klasse. Erzeuge ein neues Projekt, füge eine Klasse ein die davon erbt oder es implemententiert (um Parameter übergeben zu können).
In Eclipse lege ich das Hauptprojekt als Projektverknüpfung fest, damit ich auf die Klasse/Interface zugreifen kann. Dann mache ich aus dem Plugin eine jar, lade ichs einfach per URLClassLoader von der HDD im Hauptprojekt und rufe die geerbte/implementierte Klasse davon auf.Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
-
Hi!
Hier findet man auche in kleiens Beispielprojekt: http://www.java-blog-buch.de/d-plugi...klung-in-java/
Es gibt aber auch Frameworks, die es einem erleichtern, Plugin-fähige Anwendungen zu erstellen:
http://jpf.sourceforge.net/
Grüße!Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.
(Johann Wolfgang von Goethe)
----------------------------------------------------------------------
FLEXibler Java Entwickler
-
OK, ich danke Dir!
Hier Beispielcode für alle die den Thread finden
Zuerst das Interface im Hauptprojekt:
Jetzt das Hauptprojekt, wo das Plugin geladen werden soll:Code java:1 2 3 4 5 6
package de.unicate.playground; public interface IPlugin { public String getName(); }
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
package de.unicate.playground; import java.io.File; import java.net.URL; import java.net.URLClassLoader; public class Playground { private IPlugin plugin; private Playground() { plugin = null; } public static void main(String[] args) throws Exception{ Playground main = new Playground(); main.init(); main.start(); } private void start() { if(null != plugin) { System.out.println(plugin.getName()); } else { System.err.println("Pluginerror"); } } private void init() throws Exception { URL pluginFile = null; File file = new File("TestPlugin.jar"); if(!file.exists()) return; pluginFile = new URL("file", "localhost", file.getAbsolutePath()); URL[] urls = {pluginFile}; URLClassLoader loader = new URLClassLoader(urls,Thread.currentThread().getContextClassLoader()); plugin = (IPlugin)loader.loadClass("de.unicate.playground.plugin.PlaygroundPlugin").newInstance(); } }
Und zu guter letzt noch das Plugin, was ich in einem eigenen Projekt erstellt habe und das Hauptprojekt verknüpft habe, damit das Interface auffindbar ist:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
package de.unicate.playground.plugin; import de.unicate.playground.IPlugin; public class PlaygroundPlugin implements IPlugin{ public PlaygroundPlugin() { } @Override public String getName() { return "Ich bin ein Plugin"; } }
Relativ einfach und funktioniert!
Danke nochmal an Kai008!/* no comment */
-
20.04.10 14:00 #5
Du kannst eine File auch mit toURI.toURL (oder toURL, aber veraltet, weil keine Sonderzeichen escaped werden) umwandeln. Der 2. Parameter bei der Intialisierung des URLClassLoader ist nicht notwendig. (Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.)
Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
-
20.04.10 18:39 #6
- Registriert seit
- Jun 2002
- Ort
- Saarbrücken (Saarland)
- Beiträge
- 9.886
- Blog-Einträge
- 29
Java rocks!
How to become a good Java Programmer?
Does IT in Java and .Net
The only valid measurement of code quality: WTFs / minute
Blog
Xing
Twitter
-
OK Danke der ServiceLoader ist glaub ich genau nach was ich suche.
Aber: Wie kann ich Services dann dynamisch aus 2 oder mehr Projekten laden?Geändert von Unicate (21.04.10 um 10:12 Uhr)
/* no comment */
-
Howdie.
Ich hab praktisch identischen Code, wie du in deinem Beispielcode gezeigt hast, Unicate. Momentan arbeite ich an einem größeren Projekt, in dem einzelne Module nachladbar sein sollen.
Bei mir ist jetzt das Problem, dass ein AbstractMethodError geworfen wird, obwohl ich über
eigentlich eine Instanz erzeugt haben müsste, oder? Dieser Fehler wird ja eigentlich nur geworfen, wenn eine nicht überschriebene Methode einer abstrakten Klasse (oder wie hier eines Interfaces) aufgerufen wird.Code java:1 2
// RCBModule ist das Interface, das ich für ladbare Module benutze RCBModule module = (RCBModule)classLoader.loadClass(modulePackagePath).newInstance();
Oder muss ich den Konstruktur der implementierenden Klasse auf irgendeine Art und Weise explizit aufrufen?
Falls alle Stricke reißen muss ich halt doch auch den ServiceLoader benutzen... Wäre aber dankbar für Tipps.
Gruß
miffi"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Douglas Adams
-
21.04.10 18:37 #9
Thrown when an application tries to call an abstract method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled.
Ich lade die Klassen Problemlos mit dem URLClassLoader aus einer Jar, die ich aus einen übertragenen String der ein Server an den/die Clienten übermittelt.
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
public Plugin(File pluginFile) { super(); try { //TODO Hardcodet, read the Classes from File in Jar URLClassLoader classLoader = new URLClassLoader(new URL[] { pluginFile.toURI().toURL() }); Class<?> loadetClass = classLoader.loadClass("core.JobExecuter"); abstractJobExecuter = (AbstractJobExecuter) loadetClass.newInstance(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }
Ist das dass, was du unter dynamischen Nachladen verstehst?Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
-
Hallo Kai,
hab den Teil der Exception-Beschreibung wohl überlesen, dass der Fehler zur Laufzeit eine andere Bedeutung hat. Wobei es eigentlich logisch ist, bei dem Zugriff auf die Member einer abstrakten Klasse hätte der Compiler ja schon gemeckert.
Hab alle Module gecleant und neu kompiliert, jetzt geht alles.
Danke
Gruß
miffi"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Douglas Adams
-
22.04.10 16:37 #11
Ich habe etwas ähnliches ausprobiert und mit diesem Code eine Klasse geladen:
Danach lässt sich das jarFile aber nicht mehr löschen. Wie kann ich die Schreibrechte darauf wieder erlauben?Code java:1 2 3 4
URL url = jarFile.toURI().toURL(); URLClassLoader classLoader = new URLClassLoader(new URL[]{url}); Class<?> loadedClass = classLoader.loadClass(className); Plugin plugin = (Plugin)loadedClass.newInstance();
(Wenn ich die letzten beiden Zeilen weglasse, funktioniert das Löschen)
-
22.04.10 16:44 #12
Versuche es mal mit deleteOnExit(). Vorsicht, Memleak.
Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
-
Das Problem wird wohl sein, dass die Klasse aus dem Jar wegen des loadClass Aufrufs noch geladen ist.
Warum willst du denn das JAR zur Laufzeit löschen? Ich weiß nicht, ob es eine Möglichkeit zum "Entladen" einer Klasse gibt. Wenn du den Default-ClassLoader genommen hast, müsste dieser IMHO doch bis zur Terminierung der JVM erhalten bleiben. D.h., du müsstest die geladenen Klassen wieder rauswerfen, sonst geht das vermutlich nicht...
Würde mich auf jeden Fall auch interessieren, wenn du eine Lösung gefunden hast.
Gruß
miffi"A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools."
Douglas Adams
-
22.04.10 16:51 #14
Danke für die schnellen Antworten.

Anscheinend kann man einmal geladene Klassen nie mehr entladen.
An deleteOnExit() hab ich auch schon gedacht, es funktioniert aber widererwartend nicht.
Ich wollte das jar-File nur temporär aus einer eigenen Plugin-Datei entpacken und so schnell wie möglich wieder löschen.
Ich speichere jetzt aber alle Plugins in einem extra Ordner, in dem sie bleiben können.
-
22.04.10 16:54 #15
Würde ich sowieso so machen, nächstes mal musst du nur Filesize und/oder Checksum vergleichen.
Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
Ähnliche Themen
-
Konzept Newssammler
Von topf im Forum PHPAntworten: 1Letzter Beitrag: 03.03.09, 22:24 -
Vorlage für ein DV Konzept
Von hauke1981 im Forum SmalltalkAntworten: 0Letzter Beitrag: 11.04.07, 10:31 -
Konzept
Von webhoster im Forum PHPAntworten: 1Letzter Beitrag: 10.07.04, 02:59 -
Konzept W-LAN
Von blonde im Forum NetzwerkeAntworten: 0Letzter Beitrag: 06.03.04, 14:24 -
Programmier Konzept
Von webhoster im Forum PHPAntworten: 5Letzter Beitrag: 09.09.02, 15:12





Zitieren

Login





