Java Plugin schreiben

BlubBlub

Bekanntes Mitglied
Hi,

ich versuche ein Programm "FunnyFunctions" zu schreiben, welches erlaubt weitere Funktionen zu integrieren.

Ich habe also, das Hauptprogramm "FunnyFunctions".
Zudem habe ich einen Ordner namens "External".
In den Ordner "External" soll ein Dritter eine ".class" Datei ablegen können,
deren Funktionalität beim starten des Hauptprogramms zur Verfügung steht.

Ich sage also, dass jede ".class" Datei ein bestimmtes Interface implementieren muss,
mit den Funktionen die dem Hauptprogramm später zur Verfügung stehen sollen.
Die neue Klasse wird dynamisch über einen URLClassLoader geladen.

Allerdings habe ich ein Problem. Sowohl das Hauptprogramm als auch die neue Klasse
müssen das Interface kennen. Somit muss man jedes mal von Hand den ClassPath setzen zu dem Pfad wo sich das Interface befindet. Dies ist jedoch recht mühselig.

Mein Ziel ist es, dass ein unerfahrener Benutzer sich von irgendwo her die neue Klasse in Form einer ".class" Datei holt oder runterlädt und diese lediglich in einen bestimmten Ordner, in diesem Fall in den Ordner "External" einfügt. Anschließend soll beim Ausführen des Hauptprogramm die neue Funktionalität zur Verfügung stehen.

Frage: Wie schaffe ich es ohne immer wieder den ClassPath selbst setzen zu müssen das Interface sowohl dem Hauptprogramm als auch der neuen Klasse bekannt zu machen?

Ich habe auch einen recht interessanten Artikel gefunden zum Erstellen von Java Plugins gefunden Java Blog Buch : D) Plugin-Entwicklung in Java. Jedoch wird da immer der ClassPath von Hand gesetzt, was ich ja vermeiden will.

Damit diese beiden Klassen als Schnittstelle zwischen Plugin und Programm agieren können, müssen sowohl die Plugins, als auch die Anwendung selbst, diese beiden Interfaces kennen. Es bietet sich also an, ein eigenes PluginInterface.jar zu erstellen, welches aus dem PluginManager und dem Pluggable Interface besteht. Dieses JAR muss dann während der Entwicklung der Applikation und der Plugins als Classpath-Eintrag zur Verfügung stehen. Das Programm selbst benötigt die Schnittstelle natürlich auch beim Ausführen.
 

faetzminator

Gesperrter Benutzer
Wieso ist das mühsam? Es ist normal, das beide die Schnittstelle kennen müssen, ansonsten könnten sie gar nicht miteinander kommunizieren!
Aber es gäb da noch den hässlichen Weg, dass du einfach die Methoden (des nicht vorhandenen Interfaces) per Reflection aufrufen kannst. Die Klasse muss natürlich trotzdem all diese Methoden implementieren, auch wenn sie nicht vom Interface erbt.
 
B

bygones

Gast
du benutzt doch schon den URLClassLoader - warum soll der fuer deine Idee nicht nutzbar sein ?!

um die "plugins" zu laden brauchst du gar nix von hand machen. ueber den URLClassLoader kannst du sie einfach alle reinladen
 

BlubBlub

Bekanntes Mitglied
Wieso ist das mühsam? Es ist normal, dass beide die Schnittstelle kennen müssen, ansonsten könnten sie gar nicht miteinander kommunizieren!

Dass beide die Schnittstellen kennen müssen versteh ich ja. Aber ich denke halt, dass die meisten Benutzer, die nur Grundkenntnise besitzen, Probleme haben werden den Classpath zu setzen.
Darum fänd ichs halt gut wenn der Benutzer so wenig wie möglich machen muss. Am besten wärs, wenn die ".class" Datei in einen bestimmten Ordner einfügt werden müsste. Die meisten Benutzer werden mit dem Begriff Classpath sicherlich Schwierigkeiten haben.

Den Classpath bei dem Hauptprogramm könnte ich ja noch selbst setzen, indem ich mein Hauptprogramm in einer Jar Datei packe und in der Manifest Datei den Classpath zur Interface ".class" Datei erstelle, glaube ich. Bin mir da aber nicht ganz sicher, das muss ich erstmal ausprobieren.


du benutzt doch schon den URLClassLoader - warum soll der fuer deine Idee nicht nutzbar sein ?!
Ich verwende den URLClassLoader um ein Objekt zu laden, dessen Klasse ein bestimmtes Interface implementiert.
Das Problem welches Auftritt, wenn ich den ClassPath zur "Interface.class" Datei nicht setze, ist dass
das Objekt welches über den URLClassLoader geladen wird einen NoClassDefFoundError auslösen wird. Dies liegt daran, dass die externe Klasse fogelndes stehen hat "public MyClass implements AnInterface". Sie muss also wissen, wo sich das Interface befindet. Eine Import Anweisung ist ja nicht möglich, da sowohl das Hauptprogramm, als auch die Neue Klasse auf dieselbe ".class" Datei also auf dieselbe Interface Definition zugreifen müssen. Das Interface wird sich aber in der jar. Datei zusammen mit dem Hauptprogramm befindent. Die externe Klasse befindet sich aber in einem Ordner außerhalb der jar Datei. Ich denke das ist jetzt etwas schwer verständlich beschrieben, dass genau Problem habe ich beschrieben beim letzten Eintrag von mir: dynamische-erzeugung-objektes
 
B

bygones

Gast
ich glaub ich versteh das nicht so recht.

Du hast ein Projekt in welchem du eine API fuer andere Entwickler bereitstellst. Damit diese entwickeln koennen bietest du zb ein jar an, welches sie in ihr projekt einsetzen muessen (oder du haust ihnen alles ihn, was nicht sehr gut waere)

Sie haben dann ihr Projekt/Klasse entwickelt und legen das nun in Ordner x ab.

Dein Programm was ja im jar liegt hat seinen Classpath definiert damit es an sich startet. Zusaetzlich laedt es sich per URLClassloader den entsprechenden Ordner.

Was ist das Problem?
 

BlubBlub

Bekanntes Mitglied
Kurz worums geht: Es wird ein java.lang.NoClassDefFoundError geschmissen.
Der Fehler liegt meiner Meinung daran, dass ich die Klasse aus einem anderen
Ordner versuche zu laden die ein Interface implementiert. Dieses Interface liegt
aber nicht in dem Ordner wo die zu ladende Klasse liegt.

Was mir am meisten helfen würde, ist wenn ihr euch diesen Beispielcode anschaut und mir anhand dessen sagt was ich da genau zu ändern habe damit es funktioniert.

Fehlermeldung:
java.lang.NoClassDefFoundError: ExternalFunction


Kurze Beschreibung:
Auf dem Desktop habe ich zwei Ordner:
Ordner: "One"
Ordner: "Two"

Diese haben folgenden Aufbau:

Code:
One
  |--------- interfaces
  |                 |------------- ExternalFunction.java
  |                 |------------- ExternalFunction.class
  |
  |--------- starter
                    |------------- Starter.java
                    |------------- Starter.class
 
Two
  |---------- MyExternalClass.java
  |---------- MyExternalClass.class

Java:
package starter;
 
import interfaces.ExternalFunction;
 
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
 
public class Starter 
{
    public static void main(String[] args)
    {
        try 
        {             
            URL urls = new URL("file:\\\\\\C:\\Users\\Ich\\Desktop\\Two\\");
            URL[] classpath = {urls};
            URLClassLoader urlClassLoader = new URLClassLoader(classpath);
            Class<?> clazz = urlClassLoader.loadClass("MyExternalClass");  //Hier wird der Fehler geschmissen
            Object object = clazz.newInstance();
            ExternalFunction externalFunction = (ExternalFunction)object;
            externalFunction.doSomething();
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        } 
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (InstantiationException e)
        {
            e.printStackTrace();
        } 
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
    }
}

Java:
package interfaces;
 
public interface ExternalFunction 
{
    public String doSomething();
    public String getDescription();
}

Java:
public class MyExternalClass implements ExternalFunction
{
    public MyExternalClass(){}
     
    @Override
    public String doSomething()
    {
        System.out.println("MyExternalClass doSomething");
        return null;
    }
 
    @Override
    public String getDescription() 
    {
        String description = "MyExternalClass Description";
        return description;
    }
}

Ziel: Wie oben beschrieben. Der Benutzer soll eine Klasse welche das "ExternalFunction" Interface implementiert in den Ordner "Two" legen. Das Hauptprogramm also die "Starter" Klasse starten und dann soll die Methode der externen Klasse aufgerufen werden.
 

BlubBlub

Bekanntes Mitglied
Um keine Missverständisse hervorzurufen. Das Programm über mir funktioniert.
Aber nur unter der Bedigung, dass ich beim Compilieren der Externenen Klasse den Classpath dahin setze
wo sich das Interface befindet.

Wenn ich also eine neue Klasse schreiben, wie diese hier:
Java:
public class MyExternalClass implements ExternalFunction
{
    public MyExternalClass(){}
     
    @Override
    public String doSomething()
    {
        System.out.println("MyExternalClass doSomething");
        return null;
    }
 
    @Override
    public String getDescription() 
    {
        String description = "MyExternalClass Description";
        return description;
    }
}

Dann muss ich sie so compilieren in der windows Konsole:
C:\Users\Ich\Desktop\Two> javac -classpath C:\Users\Ich\Desktop\One MyExternalClass

So funktioniert dann alles prima. Den Classpath muss ich also setzen da sich das Interface "ExternalFunction" an einer ganz anderen Stelle befindet, nämlich im Ordner One (siehe meinen darüberliegenden Eintrag).

Mein Ziel ist es, aber dass man
-classpath C:\Users\Ich\Desktop\One
NICHT extra eingeben muss.
Denn wenn ein Dritter ein neues Plugin (also eine Neue Klasse die das Interface ExternalFunction implementiert) schreibt und er nicht im Besitz des Hauptprogramms ist, dann kann er seine Klasse nicht kompilieren. Denn beim kompilieren würde der Compiler sagen, dass er das Interface "ExternalFunction" nicht kennt.
Ich möchter aber, dass der Dritte ohne den Code des Hauptprogramm eine Klasse schreibe kann, die das Interface implementiert und anschließend die compilierte Version an jemanden per Email oder USBStick gibt, der das Hauptprogramm besitzt. Der jemand der die ".class" Datei dann erhalten hat, legt diese dann nur noch in den entsprechenden Ordner und schon ist das Hauptprogramm um ein Plugin reicher.
 
Zuletzt bearbeitet:
G

Gast2

Gast
Beim Kompilieren der Klasse MUSS das Interface dem Compiler bekannt sein. In der Regel verpackt man sowas in nen
Code:
meineApp-api.jar
file, dass man dann den Entwicklern mit ausliefert damit die ihre Plugins kompilieren können.
In dem
Code:
meineApp-api.jar
File würde dann unter anderem dein Interface liegen.
 

BlubBlub

Bekanntes Mitglied
*spam entfertn*

Beim Kompilieren der Klasse MUSS das Interface dem Compiler bekannt sein. In der Regel verpackt man sowas in nen meineApp-api.jar file, dass man dann den Entwicklern mit ausliefert damit die ihre Plugins kompilieren können.
In dem meineApp-api.jar File würde dann unter anderem dein Interface liegen.
Die schaffe ich zu realisieren. Also ist das der gängige Weg wie man Plugins erstellt?
 
Zuletzt bearbeitet von einem Moderator:
G

Gast2

Gast
Der gängiste weg ist etwas fertiges zu nutzen, wie zum Beispiel OSGi. Das kann zwar etwas mehr als das was du willst, aber plugins sind da kein Problem.
 


Schreibe deine Antwort... und nutze den </> Button, wenn du Code posten möchtest...
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Java Plugin System (ohne OSGI) Allgemeine Java-Themen 10
A Best Practice Java - eine Art Plugin-Struktur Allgemeine Java-Themen 3
J Java code "plugin" fähig machen Allgemeine Java-Themen 4
X Java Plugin Befehle Allgemeine Java-Themen 2
A Start von Java Plugin Allgemeine Java-Themen 2
N Java Plugin? Allgemeine Java-Themen 2
J Java Plugin probleme beim Laden? Allgemeine Java-Themen 3
S java plugin in firefox/chroot_x86_32 integrieren Allgemeine Java-Themen 3
F Plugin damit M$ Word Java syntax versteht? Allgemeine Java-Themen 12
G Java-Plugin für Vista (x64)? Allgemeine Java-Themen 3
S ActiveX Java Plugin Allgemeine Java-Themen 2
kodela Von C++ nach Java Allgemeine Java-Themen 1
Fey Java auf USB Stick Allgemeine Java-Themen 5
theJavaMaschine Mitstreiter gesucht: Gemeinsam Java und Android Development lernen! Allgemeine Java-Themen 5
PARAS Karriereberatung benötigt: Wie kann ich ein Java Full Stack Entwickler werden? Allgemeine Java-Themen 7
P Java Access Bridge Allgemeine Java-Themen 5
W ICEpdf PDF-Dateien werden mit Java 21 nicht nicht mehr vollständig dargestellt Allgemeine Java-Themen 3
MiMa Grundsätzliche Frage zur Verwendung von Java Versionen?? Allgemeine Java-Themen 3
OnDemand Java Deployment Vaadin Allgemeine Java-Themen 3
D Hat Java eine Library um JavaScript auszuwerten? Allgemeine Java-Themen 2
Zrebna Wieso sind eigentlich JUnit-Tests in src/test/java platziert - nur Konvention? Allgemeine Java-Themen 7
N LlaMA, KI, java-llama.cpp Allgemeine Java-Themen 39
V Java-Codierungsherausforderung: Navigieren durch die Macken der Datumsmanipulation Allgemeine Java-Themen 2
E Output Fehler (Java-Programm Kuchen) Allgemeine Java-Themen 11
M java: unexpected type Allgemeine Java-Themen 2
harrytut Java Input/Output Tests Junit Allgemeine Java-Themen 3
B Java Discord bot auf ein Root Server? Allgemeine Java-Themen 1
BetziTheRealOne Java PKIX path building failed as non Admin Allgemeine Java-Themen 15
D Linux, Java-Version wird nicht erkannt bzw. welche Einstellung fehlt noch? Allgemeine Java-Themen 19
KonradN Java 21 Release Allgemeine Java-Themen 5
V Umgang mit fehlenden Daten in einer Java-Datenanalyseanwendung Allgemeine Java-Themen 5
P Fehler: Hauptklasse Main konnte nicht gefunden oder geladen werden Ursache: java.lang.ClassNotFoundException: Main Allgemeine Java-Themen 24
K Java Anwendung machen Anleitung Allgemeine Java-Themen 5
G java.io.listFiles() Allgemeine Java-Themen 3
8u3631984 Frage zu Java Streams min / max Allgemeine Java-Themen 17
S Java Programm lässt sich vom USB-Stick starten, aber nicht von HDD Allgemeine Java-Themen 16
K Java-Projekt Allgemeine Java-Themen 11
K Java-Projekt Allgemeine Java-Themen 0
ruutaiokwu Welcher Browser unterstützt heutzutage noch Java Applets? Allgemeine Java-Themen 5
Jose05 Java-Klasse im extra cmd-Fenster ausführen Allgemeine Java-Themen 3
rode45e Java Threads Allgemeine Java-Themen 4
G java.io.listFiles() Allgemeine Java-Themen 2
N Java Dynamic Proxy Allgemeine Java-Themen 3
N Leichte Java Gegner Ki Allgemeine Java-Themen 10
A Java modul Problem Allgemeine Java-Themen 4
Thomasneuling Java Jar datei erstellen, von Projekt, dass auch Javafx Dateien, FXML Dateien und CSS Dateien, sowie Bilder enthält? Allgemeine Java-Themen 14
V Funktionale Schnittstelle in Java Allgemeine Java-Themen 3
OnDemand Java String in Hashmap als Key NULL Allgemeine Java-Themen 27
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
berserkerdq2 Wenn ich bei Intelij javafx mit maven importieren will, muss ich das in die pom.xml reintun, aber warum noch in module-info.java? Allgemeine Java-Themen 3
KonradN Java 20 am 21. März Allgemeine Java-Themen 1
O Java Website Stock Bot Allgemeine Java-Themen 3
J Front-/Backend in Java Allgemeine Java-Themen 14
doopexxx JAVA Google Webcrawler Allgemeine Java-Themen 1
J JavaScript innerhalb eines Java Projekts ausführen Allgemeine Java-Themen 2
A Java Programm erstellen hilfe Allgemeine Java-Themen 10
G java.lang.NoClassDefFoundError: org/aspectj/lang/Signature Allgemeine Java-Themen 2
lalex1491 Java Aktienkurse nachfragen Allgemeine Java-Themen 4
J Class to link Java Allgemeine Java-Themen 4
V Wie funktioniert das Schlüsselwort "final" von Java? Allgemeine Java-Themen 19
mrStudent Inferenz JAVA Allgemeine Java-Themen 6
U URI Rechner (Java Script) Allgemeine Java-Themen 7
TheSkyRider Java Geburtsdatum Textfeld Allgemeine Java-Themen 7
mihe7 Java 19 JavaDocs: Browserintegration Allgemeine Java-Themen 1
Encera Gleichzeitiges Ausführen und verbinden von 2 Java-Klassen über die Eingabeaufforderung und Eclipse Allgemeine Java-Themen 21
H Java Rechner Programmierung der Mathematik Allgemeine Java-Themen 33
Lennox Schinkel Java Kara Auf einen Java Host laufen lassen Allgemeine Java-Themen 17
C Fußnoten von DocX mit Java Allgemeine Java-Themen 2
C Fußnoten in DocX mit Java Allgemeine Java-Themen 1
MJannek Aussagenlogik in Java Programmieren Allgemeine Java-Themen 22
B Per Java Word Dokument schreiben? Allgemeine Java-Themen 8
krgewb Java-Bibliothek für ONVIF Allgemeine Java-Themen 1
KonradN Oracle übergibt (Java Teile der) GraalVM Community Edition an OpenJDK Community Allgemeine Java-Themen 2
Momo16 Brauche Hilfe - Java Projekt kann nicht erstellt werden Allgemeine Java-Themen 12
B Java mit command line und jars benutzen? Allgemeine Java-Themen 18
MJannek Java Überprüfen ob .exe-Datei bereits ausgeführt wird Allgemeine Java-Themen 2
B HTTP Allgemeine Fragen über Suchmaschine nutzen mit Java Allgemeine Java-Themen 20
Mick P. F. Wie kriege ich die Fehlermeldung "java: symbol lookup error: ..." weg? Allgemeine Java-Themen 11
K Nachhilfe Java Allgemeine Java-Themen 11
KonradN Java 19 Allgemeine Java-Themen 11
F IDEA IntelliJ Java Songliste erstellen Allgemeine Java-Themen 6
TheSepp Java bestimmtes Array auf den Wert 0 setzen Allgemeine Java-Themen 32
B Java Reflection Probleme beim wehcselseitigen Referenzieren zweier Klassen/Objekte Allgemeine Java-Themen 14
Sachinbhatt Sind alle Methoden in Java implizit virtuell Allgemeine Java-Themen 2
E Java und integrierte Grafikkarten Allgemeine Java-Themen 18
Sachinbhatt Wie wird die Typumwandlung bei Mehrfachvererbung in Java implementiert? Allgemeine Java-Themen 3
Peterw73 Hilfe bei Java gesucht Allgemeine Java-Themen 3
A Java unter Win 10 Allgemeine Java-Themen 1
B Woher kommen die Bildschirmkoordinaten beim java Robot? Allgemeine Java-Themen 14
P9cman java.Lang Klassen fehlen in JRE System Library Allgemeine Java-Themen 1
T Java Robot Class - Bot Allgemeine Java-Themen 3
E Wie Java Heap Space vergrößern? Allgemeine Java-Themen 3
B Java Programm auf virutellem Desktop laufen lassen? Allgemeine Java-Themen 1
D VBA Code mit Java ausführen möglich? Allgemeine Java-Themen 10
berserkerdq2 Threads, wie genau läuft das in Java ab? (Ich kann Threads erstellen und nutzen, nur das Verständnis) Allgemeine Java-Themen 6
izoards Java Home Pfad unabhängig von der Version Allgemeine Java-Themen 7
N JAVA-Code mit Grafikfenster zeichnet in Windows, aber nicht Mac. Allgemeine Java-Themen 4
L Java überprüfen lassen, ob sich ein gegebener Pfad / das Programm an sich auf einer CD oder Festplatte befindet Allgemeine Java-Themen 14
KonradN CVE-2022-21449: Fehler in Java bei Signaturprüfung Allgemeine Java-Themen 20
berserkerdq2 Java sql Allgemeine Java-Themen 15

Ähnliche Java Themen

Neue Themen


Oben