In Java werden Klassen von speziellen Objekten, den Klassenladern (class loaders), in den Speicher geladen. Jeder Klassenlader bildet seinen eigenen Namensraum für Klassen.
Arten von Klassenladern:
$JAVA_HOME/lib/ext.Besonderheiten:
Kann man mehrere Versionen derselben Klasse im JVM-Prozess laden und wie kann man das machen?
Antwort: Ja, das ist möglich, wenn man unterschiedliche Klassenlader verwendet. Klassen mit demselben FQDN, die von verschiedenen Ladern geladen werden, gelten als unterschiedliche Typen für die JVM.
Beispiel:
ClassLoader loader1 = new URLClassLoader(new URL[]{...}); ClassLoader loader2 = new URLClassLoader(new URL[]{...}); Class clazz1 = loader1.loadClass("com.example.MyClass"); Class clazz2 = loader2.loadClass("com.example.MyClass"); System.out.println(clazz1 == clazz2); // false
Geschichte
In einem großen Serversystem wurden Plugins verwendet, von denen jedes über einen separaten benutzerdefinierten Klassenlader angeschlossen wurde. Die Plugins tauschten Objekte über ein gemeinsames Interface aus, das ebenfalls von seinem Klassenlader geladen wurde. Es trat eine ClassCastException bei Typumwandlungen auf, da das Interface 'PluginApi' aus dem Klassenlader des Plugins und das der Hauptanwendung als unterschiedliche Typen angesehen wurde.
Geschichte
Der Versuch, einen Servlet "hot" über einen benutzerdefinierten Klassenlader neu zu laden, führte zu Speicherlecks — die alte Klasse wurde nicht aus dem Speicher entfernt, da irgendwo in statischen Variablen ein Verweis blieb. Infolgedessen überfüllte sich PermGen schnell.
Geschichte
Ein Produkt mit Unterstützung für das dynamische Laden von Modulen verwendete implizit den Systemklassenlader, während die Entwickler versehentlich dessen Elternteil überschrieben und den Zugriff auf grundlegende Klassen (z.B. aus dem JDK) verloren. Dies führte zu Abstürzen, wenn das neue Modul die Standard-Java-Klassen wie
java.sql.Drivernicht laden konnte.