Frage

Ich habe einen Lader benutzerdefinierte Klasse, so dass eine Desktop-Anwendung dynamisch Laden von Klassen aus einer AppServer beginnen kann ich reden müssen. Wir taten dies, da die Menge der Gläser, die dies sind lächerlich sind erforderlich, um zu tun (wenn wir sie versenden wollten). Wir haben auch Probleme Version, wenn wir die Klassen laden nicht dynamisch zur Laufzeit aus der AppServer Bibliothek.

Nun, ich traf nur ein Problem, wo ich brauche, um zwei verschiedene AppServers zu sprechen und stellte fest, dass in Abhängigkeit von den Klassen ich zuerst laden schlecht ich brechen könnte ... Gibt es eine Möglichkeit das Entladen der Klasse zu zwingen, ohne tatsächlich zu töten die JVM?

Hope dies macht Sinn

War es hilfreich?

Lösung

Die einzige Möglichkeit, dass eine Klasse entladen werden kann, ist, wenn die verwendete Classloader Müll gesammelt wird. Dies bedeutet, Verweise auf jede einzelne Klasse und den Classloader selbst müssen den Weg des Dodo gehen.

Eine mögliche Lösung für Ihr Problem ist es, einen Classloader für jede JAR-Datei zu haben, und ein Classloader für jeden des AppServers, dass die Delegierten die tatsächliche Belastung von Klassen zu bestimmten Jar Classloader. Auf diese Weise können Sie verschiedene Versionen der JAR-Datei für jeden App-Server verweisen können.

Das ist nicht trivial, though. Die OSGi-Plattform strebt genau dies zu tun, da jedes Bündel einen anderen Classloader und Abhängigkeiten werden von der Plattform gelöst. Vielleicht wäre eine gute Lösung, die einen Blick auf sie zu nehmen.

Wenn Sie wollen OSGi nicht verwenden, das eine mögliche Implementierung könnte sein, eine Instanz zu verwenden JarClassloader Klasse für jede JAR-Datei.

Und erstellen Sie eine neue, MultiClassloader Klasse, die Classloader erstreckt. Diese Klasse intern würde ein Array (oder Liste) von JarClassloaders, und in der defineClass () -Methode würde durch alle internen Classloader, bis eine Definition iterieren gefunden werden kann, oder ein NoClassDefFoundException geworfen wird. Ein paar Accessormethoden bereitgestellt werden neue JarClassloaders zur Klasse hinzuzufügen. Es gibt mehrere mögliche Implementierungen auf dem Netz für eine MultiClassLoader, so dass Sie vielleicht nicht einmal benötigen, um Ihre eigene zu schreiben.

Wenn Sie eine MultiClassloader für jede Verbindung zum Server instanziiert im Prinzip ist es möglich, dass jeder Server eine andere Version derselben Klasse verwendet.

Ich habe die MultiClassloader Idee in einem Projekt verwendet, wo Klassen, die enthielten benutzerdefinierte Skripte geladen und aus dem Speicher und es funktionierte recht gut ausgeladen werden mußten.

Andere Tipps

Ja, es gibt Möglichkeiten, Klassen zu laden und sie zu „entladen“ wiederzufinden. Der Trick ist, Ihre eigene Klassenlader zu implementieren, die zwischen hohen Klassenlader (Systemklassenlader) und den Klassenlader des App-Server (n), und zu hoffen, dass der App-Server des Classloader befindet sich das Classloading zu den oberen Lader delegieren .

Eine Klasse wird durch sein Paket definiert, seinen Namen, und die Klassenlade es ursprünglich geladen. Ein ein „proxy“ Klassenladeprogramm, das ist die erste, die geladen wird, wenn die JVM beginnend. Workflow:

  • Das Programm startet und die eigentliche „Haupt“ -Klasse von diesem Proxy Classloader geladen wird.
  • Jede Klasse, die dann normalerweise geladen wird (das heißt nicht durch eine andere Implementierung Klassenlader, der die Hierarchie brechen könnte) werden an diese Klassenlader delegiert werden.
  • Die Proxy-Classloader Delegierten java.x und sun.x an das System Classloader (diese muss nicht durch andere Klassenlader als das System Classloader geladen werden).
  • Für jede Klasse, die austauschbar ist, instanziiert ein Klassenlader (was wirklich die Klasse lädt und delegieren nicht an die Eltern Classloader) und durch diese geladen werden.
  • Geschäft das Paket / Namen der Klassen als Schlüssel und den Klassenlader als Werte in einer Datenstruktur (d.h. HashMap).
  • Jedes Mal, wenn der Proxy-Classloader eine Anforderung für eine Klasse bekommt, die vorher geladen wurden, ist es die Klasse aus dem Klassenlader liefert gespeichert vor.
  • Es sollte ausreichen, um die Byte-Array einer Klasse von Ihrem Klassenlader zu suchen (oder zu „löschen“ den Schlüssel / Wert-Paar aus der Datenstruktur) und laden Sie die Klasse, wenn Sie es ändern möchten.

Fertig Recht sollte es nicht kommen, eine Classcast oder LinkageError etc.

Weitere Informationen über Klassenlade Hierarchien (ja, das ist genau das, was Sie setzen hier, -) buchen, “ Server-basierte Java-Programmierung“von Ted Neward - das Buch hat mir geholfen, etwas sehr ähnlich zu der Umsetzung, was Sie wollen

.

Ich schrieb einen benutzerdefinierten Classloader, von dem es möglich ist, einzelne Klassen zu entladen, ohne den Klassenlader GCing. Jar Class Loader

Classloader kann ein heikles Problem. Sie können vor allem auf Probleme stoßen, wenn Sie mehrere Klassenladeprogramme verwenden und nicht über ihre Wechselwirkungen klar und streng definiert. Ich denke, um tatsächlich in der Lage sein, eine Klasse zu entladen youlre gehen gehen müssen alle Verweise auf alle Klassen entfernen (und deren Instanzen) Sie versuchen zu entladen.

Die meisten Menschen brauchen diese Art der Sache zu tun, am Ende mit OSGi . OSGi ist wirklich mächtig und überraschend leicht und einfach zu bedienen,

Sie können eine Klassenladeprogramm entladen, aber Sie können bestimmte Klassen nicht entladen. Insbesondere können Sie keine Klassen in einem Klassenladeprogramm erstellt entladen, die nicht unter Ihrer Kontrolle ist.

Wenn möglich, ich schlage vor, Ihre eigenen Classloader verwenden, so dass Sie entladen können.

Klassen haben einen impliziten starken Bezug auf ihre Klassenladeprogramm-Instanz, und umgekehrt. Sie sind Müll gesammelt, wie mit Java-Objekten. Ohne die Werkzeuge Schnittstelle oder ähnliches zu schlagen, können Sie einzelne Klassen nicht entfernen.

Wie auch immer Sie Speicherlecks zu bekommen. Jede starke Bezugnahme auf eine Ihrer Klassen oder Klassenlader undicht wird die ganze Sache. Dies geschieht mit den Sun-Implementierungen von Thread, java.sql.DriverManager und java.beans, zum Beispiel.

Wenn Sie Live beobachten, wenn Entladen Klasse arbeitet in

scroll top