Nachladen von Klassen zur Laufzeit

Detlef Bosau

Mitglied
Ich stelle die Frage mal hier, ich habe das nie wirklich mal nachgelesen. In C++ kann ich (iirc je nach OS und Laufzeitumgebung) Bibliotheken, also damit auch Klassen, zur Laufzeit eines Programms dynamisch nachladen.

Ist dies in Java auch vorgesehen? Oder müssen alle benötigten Klassen beim Programmstart im Klassenpfad liegen?
 

Marinek

Bekanntes Mitglied
Das geht mit Java via Reflection. Ich habe es zwar dynamisch zur Laufzeit nicht gemacht, es das sollte ein Anfang sein:


Java:
URLClassLoader cl = URLClassLoader.newInstance(new URL[] {myJarFiles});
Class myClass = cl.loadClass("<Klasse angeben>");
Method method= myClass.getMethod("machMethode", new Class[] {String.class, String.class});
Object myClassObj = myClass.newInstance();
Object response = method.invoke(myClassObj, "String1", "String2");

Du wirst in dem aufrufenden Stück Code ein paar Interfaces definieren müssen, damit du hier mit weniger Reflection auskommst.
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Im Prinzip kannst du damit auch wieder Bibliotheken entladen und auch verschiedene Versionen einer Bibliothek gleichzeitig nutzen.
Wobei das auch mit Hilfe des normalen Classloaders geht. Einfach mehrere Classloader und die Library (ggf. in unterschiedlichen Versionen) laden.

Das "Entladen" läuft genau so, wie bei allen Instanzen. Da darf es dann halt keine Referenzen mehr geben, damit der GC aktiv wird. Das Bedeutet also: Alle Instanzen von Klassen sowie der ClassLoader müssen ohne Referenz sein, damit der GC aktiv wird.

Das nur ganz am Rande - 1999 / 2000 rum habe ich sowas mal gebaut :)
 

KonradN

Super-Moderator
Mitarbeiter
Also der TE hat das nicht mit gefordert. Beim Vergleich mit C++ ist das doch deutlich: Da wird er ja auch auf Libraries zugreifen und nicht erst irgendwelche Projekte bauen.

Die Antwort #8 ist also mehr spezifisch für Dich, weil ich das als zusätzliche Frage / Interesse von Dir verstanden habe.

Aber das muss man nicht diskutieren - Möglichkeiten sind benannt - unabhängig davon ob der TE das braucht oder nicht.
 

KonradN

Super-Moderator
Mitarbeiter
Wenn ich die Anwendungslogik bereits compiliert vorliegen habe, dann macht es keinen Sinn, die Klassen erst im Nachhinein zu laden.
Wieso denn das nicht? Ich kann mir viele Szenarien vorstellen, wo sowas Sinn macht. Man muss sich nur die ganze Thematiken anschauen, wo man mit Plugins arbeitet.

Wenn man sich etwas aus den Fingern saugen muss, dann nimmt man einfach die IntelliJ Plugins: Man kann ein Plugin herunter laden und es ist direkt aktiv. Man muss IntelliJ nicht neu starten. (Und das Laden einer neuen Version erfordert ein Neustart - da ist halt das Thema "Entladen" nicht umgesetzt worden (Das macht halt einiges deutlich komplizierter - das macht aus Meiner Sicht auch wenig Sinn vom Nutzen/Kosten Aspekt her!)
 

Detlef Bosau

Mitglied
Wenn ich die Anwendungslogik bereits compiliert vorliegen habe, dann macht es keinen Sinn, die Klassen erst im Nachhinein zu laden. Insofern habe ich seine Frage so verstanden, dass er beides will...
Ich werde es nicht in näherer Zeit brauchen.

Und jein, die Anwendungslogik muß nicht zwingend ganz fertig sein, im Grunde rede ich vom Anwendungsfall einer "abstract factory". Es ist gewiss 10 Jahre oder länger her, daß ich damit mal gespielt habe, aber da kannst du meinethalben bei laufendem Programm eine Bibliothek von einer webseite laden und ins Programm mit reinschieben. das wurde damals aber nicht von allen Unices unterstützt. BSD, Linux ja, bei system v weiß ich es nicht.
 

Detlef Bosau

Mitglied
Ich bringe mal ein Stück c++ um deutlich zu machen, wo es bei mir im Kopf gerade hängt. (Irgendwie habe ich es überlebt, habe wohl bald 15 Jahre kein c++ ,mehr gemacht.)

C++:
#include <iostream>

struct s {
  int a; int b;
  s(){
    std::cout << "Hello World!" ;
    std::cout << std::endl;
  };
} anon ;
int main() {

  return 0;
}

Die main Methode macht nichts. (Präziser: Sie macht nichts und meldet brav, daß dabei nichts schief gegangen ist.)

Die "Arbeit" macht die Definition anon. Diese Definition führt dazu, daß ein Objekt der Klasse s erzeugt wird. Diese Klasse s könnte jetzt eine concrete factory sein und der Konstruktor würde diese concrete factory etwa in einer Registry einfügen und ein Programm könnte die dort abgreifen und dann mit concrete_factory.getInstance(); die gewünschte Instanz bekommen.

In "Java Denk" wäre dieses "anon'" eine Instanz, die mit der Klasse mitgeliefert wird. Gewissermassen eine "statische Instanz". Und wesentlich ist, daß ich dabei dem Constructor Code unterschiebe.

Wie macht das ein classloader?
 

KonradN

Super-Moderator
Mitarbeiter
Also damit etwas passiert muss aber ja auch dort erst eine "Instanz" erzeugt werden. Das ist halt bei Dir nur der Fall, da das dort ja ausgeführt wird.

In Java musst Du also auch erst dafür sorgen, dass eine Klasse geladen wird. Sonst wird da nichts ausgeführt.

Ohne ganz genau zu wissen, was Du willst, wäre meine Vermutung jetzt, dass Du vermutlich etwas willst, was der ServiceLoader macht. (Weshalb @mihe7 den auch noch erwähnt hat). Dann kannst Du Dir einen Service-Namen überlegen. Die jar Datei kann dann dazu eine Klasse beinhalten. Der Service Eintrag besagt dann in erster Linie, welche Klasse den Service bereit stellt.

Die Klasse ServiceLoader enthält auch eine Übersicht, wie das aussehen könnte:
ServiceLoader (Java Platform SE 8 ) (oracle.com)
 

Detlef Bosau

Mitglied
Also damit etwas passiert muss aber ja auch dort erst eine "Instanz" erzeugt werden. Das ist halt bei Dir nur der Fall, da das dort ja ausgeführt wird.

In Java musst Du also auch erst dafür sorgen, dass eine Klasse geladen wird. Sonst wird da nichts ausgeführt.

Ohne ganz genau zu wissen, was Du willst, wäre meine Vermutung jetzt, dass Du vermutlich etwas willst, was der ServiceLoader macht. (Weshalb @mihe7 den auch noch erwähnt hat). Dann kannst Du Dir einen Service-Namen überlegen. Die jar Datei kann dann dazu eine Klasse beinhalten. Der Service Eintrag besagt dann in erster Linie, welche Klasse den Service bereit stellt.

Die Klasse ServiceLoader enthält auch eine Übersicht, wie das aussehen könnte:
ServiceLoader (Java Platform SE 8 ) (oracle.com)
Zumindest hilft das weiter. Laden mußt du die Klassen in C++ natürlich auch, die liegen dann in .so Dateien oder sowas und du mußt die zur Laufzeit dann laden. Das elegante ist, daß sich eine Factory dann selber etwa in einer Registry eintragen kann und damit zur Verfügung steht. Und jetzt möchte ich verstehen, wie ich das in Java nachbilden kann.
 

mihe7

Top Contributor
Das elegante ist, daß sich eine Factory dann selber etwa in einer Registry eintragen kann und damit zur Verfügung steht. Und jetzt möchte ich verstehen, wie ich das in Java nachbilden kann.
In Java läuft sowas über Service Provider Interfaces (SPI) im Zusammenhang mit dem ServiceLoader.

Du definierst ein Interface, das die Methoden deklariert, die das "Plugin" implementieren muss. Das Plugin wiederum implementiert das Interface. "Registriert" wird das über eine simple Textdatei, die sich im Plugin im Verzeichnis META-INF/services befinden und den full qualified name des Interfaces tragen muss. Inhalt ist dann der full qualified name der Implementierung.

Über den ServiceLoader kannst Du nun einfach Instanzen von Implementierungen des Interfaces (sprich: Service-Instanzen) abrufen. Das ist aber alles in der Doku zu ServiceLoader beschrieben.

Verbunden mit dem URLClassLoader (oder Varianten davon) ergibt dann ein Plugin-System, bei dem man zur Laufzeit Plugins hinzufügen kann.
 

Detlef Bosau

Mitglied
In Java läuft sowas über Service Provider Interfaces (SPI) im Zusammenhang mit dem ServiceLoader.

Du definierst ein Interface, das die Methoden deklariert, die das "Plugin" implementieren muss. Das Plugin wiederum implementiert das Interface. "Registriert" wird das über eine simple Textdatei, die sich im Plugin im Verzeichnis META-INF/services befinden und den full qualified name des Interfaces tragen muss. Inhalt ist dann der full qualified name der Implementierung.

Über den ServiceLoader kannst Du nun einfach Instanzen von Implementierungen des Interfaces (sprich: Service-Instanzen) abrufen. Das ist aber alles in der Doku zu ServiceLoader beschrieben.

Verbunden mit dem URLClassLoader (oder Varianten davon) ergibt dann ein Plugin-System, bei dem man zur Laufzeit Plugins hinzufügen kann.
 

Detlef Bosau

Mitglied
Ich habe es noch nicht im einzelnen nachvollzogen, aber der Service Loader kann mir eine Instanz der geforderten Klasse liefern? Das ist natürlich sehr elegant, da muss ich also gar nicht eine geeignete Factory bauen, der Service Loader hat das schon im, Bauch?
 

Oneixee5

Top Contributor
Ich denke der Service Loader ist nicht unbedingt was du suchst. Du hast nach dynamischen Nachladen außerhalb des Classpath gefragt. Um den Service Loader zu nutzen müssen aber die Klassen bereits dem Classpath/Classloader bekannt sein und geladen werden können. Service Loader initialisieren aber lediglich eine konkrete Instanz hinter einer Schnittstelle. Also eine Art Plugin-System. Mit der Frage aus #1 hat das aber nur bedingt zu tun.
 

KonradN

Super-Moderator
Mitarbeiter
Ich habe es noch nicht im einzelnen nachvollzogen, aber der Service Loader kann mir eine Instanz der geforderten Klasse liefern? Das ist natürlich sehr elegant, da muss ich also gar nicht eine geeignete Factory bauen, der Service Loader hat das schon im, Bauch?
Ja, so in der Art.

Hast Du Dir den ServiceLoader mit dem Beispiel in der Dokumentation einmal angesehen? Dort ist ja das Beispiel eines Services com.example.CodecSet gegeben. Das wäre also die Klasse, von der dann die Service Klassen erben sollen.

Die jar Datei enthält dann die Datei META-INF/services/com.example.CodecSet mit dem Namen der Implementation.

Nun kann der ServiceLoader genau so eine Instanz erzeugen. Wichtig ist: Das ist in der Regel erst die Klasse, die dann gewisse andere Implementationen holen kann. So ist das Beispiel ein getEncoder / getDecoder mit einem Parameter.

Also kann man sich alle implementierenden Services holen, und alle nach einem bestimmten Parameter fragen.

Ein Beispiel, wo das z.B. auch angewendet wird, sind jdbc Treiber. Es gibt dann Services, die sozusagen einen Datenbank Treiber laden können. Und dann kann also jeder Treiber gefragt werden: Hast Du einen Treiber für xyz? (Also z.B. für mysql. Der postgres Treiber wird dann sagen: "Hab ich nicht", aber der mysql Treiber wird sagen: "Jo, nimm den hier!" (Das war jetzt extrem bildlich aber ich denke, du hast das Bild damit bekommen.)

Generell sind das aber zwei Paar Schuhe:
a) Die Klassen erst einmal selbst laden können.
b) dann den Service verfügbar machen.

Der erste Punkt a ist also die Erzeugung eines ClassLoaders, der dann die zusätzlichen Klassen lädt.
Der zweite Punkt nutzt die von @mihe7 in #10 verlinkte Methode load, die auch den ClassLoader als Parameter übergeben bekommt.


An der Stelle auch noch der Hinweis: in #3 gab es auch schon den Hinweis von @Oneixee5 zu OSGi.

Die Frage ist halt, was genau Du brauchst.
Man kann sich hier das eine oder andere selbst bauen. Bei einfachen Ansprüchen geht es ganz schnell und es ist nicht besonders komplex. Sobald aber die Ansprüche steigen, dann kann man sich überlegen, ob ein OSGi Container (Eclipse Equinox, Apache Felix oder Apache Karaf) und die Erzeugung von OSGi Bundles (das kann schon ein einfaches maven-bundle-plugin mit minimaler Config sein) nicht ein besserer Ansatz sein könnte. Aber es kommen halt doch deutliche Abhängigkeiten und auch etwas mehr Komplexität hinzu. (Aber es ist eine bekannte Komplexität. Du hast da nicht etwas selbstgebautes und da muss man erst rein kommen, sondern man hat etwas vor sich, das ggf. bekannt ist und wenn nicht, dann kann man sich da gezielt schnell einarbeiten.)
 

Detlef Bosau

Mitglied
Derzeit brauchen tue ich es gar nicht, es geht mir gerade um eine gewisse Vergangenheitsbewältigung, das würde hier zu weit führen. Ich habe das SPI gestern nur quergelesen, und ja, das leistet wohl das gewünschte.

Stand das in Java von Anfang an zur Verfügung oder wurde es erst später eingeführt, wenn ja: wann?
 

KonradN

Super-Moderator
Mitarbeiter
Man hat einfach die Klassen / Ressourcen, die man braucht, geladen.

Bei alten JDBC Dokumentationen findet man das z.B. noch. Da gab es dann ein Class.forName("a.b.c.WhateverDriver");
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Dyn. Nachladen von veränderten Klassen in Multiprozesssystem Java Basics - Anfänger-Themen 25
C Klassen Class Files nachladen (mehrer .jar Dateien) Java Basics - Anfänger-Themen 2
G JAR zur Laufzeit nachladen Java Basics - Anfänger-Themen 2
G Klasse dynamisch nachladen: Fehler Java Basics - Anfänger-Themen 9
J Methodenaufrufe abstrakte Klassen, Interfaces Java Basics - Anfänger-Themen 17
M Abstrakte Klassen - Notation Java Basics - Anfänger-Themen 9
M Anonyme Klassen - Warum wird in der Konsole nichts ausgegeben? Java Basics - Anfänger-Themen 1
MoxMorris Einige Methoden aus verschiedenen Klassen nacheinander auszuführen läuft seltsam Java Basics - Anfänger-Themen 2
I Klassen von einem package laden, Statisches Feld auslesen und Objekt erstellen Java Basics - Anfänger-Themen 8
I 2 verschiedene Klassen mit gleichen Property vergleichen Java Basics - Anfänger-Themen 13
C Array von Klassen Java Basics - Anfänger-Themen 2
monsterherz 2 Klassen daher Probs mit dem Dateinamen Java Basics - Anfänger-Themen 9
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 9
I JPA Query für mehrere Klassen Java Basics - Anfänger-Themen 3
I @Entity Klassen, Service Beans etc. aus einem Share Projekt beziehen? Java Basics - Anfänger-Themen 26
S IntelliJ geht alle Klassen durch Java Basics - Anfänger-Themen 9
I Gleiche Klassen und Methoden in unterschiedlichen Projekten nutzen Java Basics - Anfänger-Themen 2
T variablen klassen übergreifend Java Basics - Anfänger-Themen 12
N Klassen Methoden anderer Klassen aufrufen Java Basics - Anfänger-Themen 4
D Klassen Klassen Kommunikation Java Basics - Anfänger-Themen 12
Encera Auf Objekte aus anderer Klassen zugreifen Java Basics - Anfänger-Themen 20
berserkerdq2 Zwei Klassen Erben von der Klasse A, die eine Klasse kann ich an Methoden übergeben, die als Parameter A haben, die andere nicht? Java Basics - Anfänger-Themen 3
M Andere Methoden in anderen Klassen aufrufen Java Basics - Anfänger-Themen 11
L Methoden in anderen Klassen nutzen Java Basics - Anfänger-Themen 6
D Klassen und Vererbung Java Basics - Anfänger-Themen 2
L Best Practice Annotierte Klassen im Classpath herausfinden Java Basics - Anfänger-Themen 1
P Mit dem Scanner Klassen aufrufen Java Basics - Anfänger-Themen 3
O Klassen Zusammenspiel zwischen 2 Klassen Java Basics - Anfänger-Themen 1
K Zweite Ausgabe von vererbten Klassen Java Basics - Anfänger-Themen 3
M Wie können Klassen nicht-materialisierte Attribute haben, die nur über get/ set-Mehoden simuliert sind? Java Basics - Anfänger-Themen 6
Speedrunner klassen aufrufen Java Basics - Anfänger-Themen 41
M Log4J (v2) nachträglich in allen Klassen hinzufügen Java Basics - Anfänger-Themen 9
D importieren eigener Klassen Java Basics - Anfänger-Themen 12
W Wo ist der Wurm in meinem Grundverständnis von Klassen? Java Basics - Anfänger-Themen 22
S Daten/Klassen/Packages richtig updaten!? Java Basics - Anfänger-Themen 2
alice98 Erste Schritte Liste erstellen ohne vorgefertigte Klassen Java Basics - Anfänger-Themen 1
C Archiv für eigene Klassen Java Basics - Anfänger-Themen 9
S Objekte von zwei klassen in zwei verschiedene Textdateien schreiben Java Basics - Anfänger-Themen 5
elsaaaaaa Wochentag als String ausgeben mit JDK Klassen Java Basics - Anfänger-Themen 6
CptK Generics: Klassen die Interface implementieren, aber selbst nicht das Interface sind Java Basics - Anfänger-Themen 8
Z Mehtode bei Start des Programms ausführen (Klassen übergreifend) Java Basics - Anfänger-Themen 12
J Allgemeines Problem mit Klassen Java Basics - Anfänger-Themen 5
TimoN11 Java Klassen Global einbinden Java Basics - Anfänger-Themen 1
B Inventar als einzelne Klassen anlegen? Java Basics - Anfänger-Themen 12
G Java Klassen und Instanzmethoden Java Basics - Anfänger-Themen 15
C Kommunikation zwischen 2 Klassen Java Basics - Anfänger-Themen 3
T Vererbung Verschiedene Attribute für vererbte Klassen Java Basics - Anfänger-Themen 4
S Klassen instanziieren und verwenden von Getter und Setter Java Basics - Anfänger-Themen 4
B Variablen Variablen übertragen ohne Klassen Java Basics - Anfänger-Themen 5
C Fernseher-Aufgabe (Methoden, Klassen und Objekte) Java Basics - Anfänger-Themen 63
H Methoden in großen Klassen gruppieren oder auslagern? Java Basics - Anfänger-Themen 10
G Abstrakte Klassen Java Basics - Anfänger-Themen 11
Y Klassen Klassen und Objekte Java Basics - Anfänger-Themen 3
Y Klassen Klassen und Objekte mit set und get Java Basics - Anfänger-Themen 0
A Generischen Klassen Java Basics - Anfänger-Themen 8
A Vererbung Klassen im Bezug auf Auto´s Java Basics - Anfänger-Themen 18
A Generische Klassen/Interface Java Basics - Anfänger-Themen 1
A Klassen Vererbung und zusätzliche Unterklassen Java Basics - Anfänger-Themen 23
J 2 klassen benutzen Java Basics - Anfänger-Themen 5
A Klassen und methoden Java Basics - Anfänger-Themen 15
A Bankweverwaltung mit Klassen und Methoden Java Basics - Anfänger-Themen 14
J Klassen Problem Java Basics - Anfänger-Themen 8
I Java Klassen "Graphics" und "MouseEvent" kombinieren Java Basics - Anfänger-Themen 7
I Klassen als Datentyp nutzen? Java Basics - Anfänger-Themen 11
M Aufsplitten von Methoden in andere Klassen Java Basics - Anfänger-Themen 2
M (Sehr großes Problem) Listen als static in anderen Klassen verwendet Java Basics - Anfänger-Themen 12
C Klassen objektorientiert aufteilen Java Basics - Anfänger-Themen 6
hello_autumn Klassen Anzahl sowie die Anzahl der Junit Tests ermitteln? Java Basics - Anfänger-Themen 8
A Auf Eigenschaften von Objekten anderer Klassen zugreifen Java Basics - Anfänger-Themen 5
F Klassen und Pakete Projektübergreifend (Eclipse) Java Basics - Anfänger-Themen 6
V_Fynn03 Klassen Überweisungen tätigen und einzahlen mit 2 Klassen Java Basics - Anfänger-Themen 1
W Abarbeitungsreihenfolge Anonyme Klassen Java Basics - Anfänger-Themen 2
V_Fynn03 Bruchrechner programmieren (2 Klassen) Java Basics - Anfänger-Themen 9
D OOP- Eine Klasse in mehrere Klassen aufteilen Java Basics - Anfänger-Themen 7
J Problem mit Array: 2 Klassen Java Basics - Anfänger-Themen 2
W Frage zu anonymen Klassen Java Basics - Anfänger-Themen 4
Curtis_MC Parameter-Übergabe bei Klassen und Methoden Java Basics - Anfänger-Themen 12
E Klassen implementieren Java Basics - Anfänger-Themen 94
T Interfaces in erbenden Klassen Java Basics - Anfänger-Themen 2
C Methoden/Klassen Übergabewerte Java Basics - Anfänger-Themen 8
C Java Klassen/Methoden/Übergabeparameter Java Basics - Anfänger-Themen 4
L Wie geht man bei mehreren Action Klassen vor? Java Basics - Anfänger-Themen 0
P Datentypen, Klassen, Operatoren, Wrapperklassen Java Basics - Anfänger-Themen 2
L Wie teilt man ein Programm in vernünftige Klassen ein? Java Basics - Anfänger-Themen 10
T Klassen Denkfehler im Klassen "dynamisch" instanzieren? Java Basics - Anfänger-Themen 4
P Zugriff auf Variablen anderer Klassen in Greenfoot Java Basics - Anfänger-Themen 1
A Methode, Klassen Java Basics - Anfänger-Themen 3
B UML Klassen Diagramm zu Java Code Programmieren und ausführen Java Basics - Anfänger-Themen 21
J Zwei Klassen die sich gegenseitig referenzieren - Bad practice? Java Basics - Anfänger-Themen 4
G Klassen und Objekte Java Basics - Anfänger-Themen 2
Java The Hutt SetWerte über verschiedene Klassen Java Basics - Anfänger-Themen 16
D Klassen ausgeben Java Basics - Anfänger-Themen 2
H linkedlist generische klassen Java Basics - Anfänger-Themen 169
B CSS Klassen in eine Liste schreiben Java Basics - Anfänger-Themen 4
Queiser Nicht statische Klassen Java Basics - Anfänger-Themen 6
neerual Klassen Wie rufe ich Klassen, die andere Klassen extenden in einer Test Unit auf? Java Basics - Anfänger-Themen 10
J Gleiche Methode in 2 verschiedenen Klassen - Lösung ? Java Basics - Anfänger-Themen 8
G Refactoring von mehreren identischen Klassen Java Basics - Anfänger-Themen 36
O Wrapper Klassen Java Basics - Anfänger-Themen 6
CptK Best Practice Klassendiagramm aus fertigen Klassen erstellen lassen Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben