ClassLoader ist eine spezielle Komponente in der JVM, die für das Laden des Bytecodes von Klassen in den Speicher bei deren erster Verwendung zuständig ist. Er ermöglicht das dynamische Nachladen von Klassen aus verschiedenen Quellen (Dateisystem, Netzwerk, Archive usw.).
Typen von ClassLoadern:
jre/lib/ext.ClassLoader implementiert Delegierung: Zuerst versucht er, die Klasse mit dem übergeordneten Loader (parent-first) zu laden, nur wenn das fehlschlägt, sucht er selbst.
Klassenisolation: Jeder ClassLoader erstellt seinen eigenen "Sichtbarkeitsbereich" für Klassen. Zwei Klassen mit demselben Namen, die von unterschiedlichen Loadern geladen werden, werden innerhalb der JVM als unterschiedliche Typen angesehen.
Beispiel für die Erstellung eines eigenen Loaders:
class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // Ihr Code zum Suchen und Laden des Bytecodes der Klasse return super.findClass(name); } }
Können zwei Klassen mit demselben Namen, die von verschiedenen Loadern geladen werden, innerhalb der JVM als dieselbe Klasse betrachtet werden?
Antwort: Nein! Die JVM betrachtet eine Klasse als einzigartig basierend auf dem Paar (voller Klassenname, ClassLoader). Deshalb werden dieselben Klassen, die von verschiedenen Loaders geladen werden, als unterschiedlich angesehen.
Geschichte
In einer Enterprise-Anwendung mit Unterstützung für eine Plug-in-Architektur wurden Plugins von separaten ClassLoadern geladen. Infolgedessen führte der Versuch, ein Objekt des Typs Interface (PluginInterface) zwischen der Hauptanwendung und dem Plugin zu übergeben, zu einer ClassCastException, weil dasselbe Interface von verschiedenen Loaders geladen wurde.
Geschichte
Bei Verwendung eines benutzerdefinierten ClassLoaders wurde das Delegieren an den übergeordneten Loader nicht implementiert. Dies führte zum erneuten Laden standardbibliotheksklassen, was zu seltsamen ClassCastException- und LinkageError-Fehlern führte.
Geschichte
In einem großen Java EE-Server luden verschiedene Anwendungen ihre Versionen derselben Bibliothek. Nachlässigkeit bei der Einstellung der Loader-Kette führte dazu, dass Klassen zwischen den Anwendungen überschneiden, was einmal zu einem massiven Speicherleck und Abstürzen aufgrund von Versionskonflikten führte.