In Java worden klassen in het geheugen geladen door speciale objecten - class loaders. Elke class loader creëert zijn eigen zichtbaarheidsscope voor klassen.
Soorten class loaders:
$JAVA_HOME/lib/ext.Kenmerken:
Is het mogelijk om meerdere versies van dezelfde klasse in het JVM-proces te laden, en hoe kan dat gedaan worden?
Antwoord: Ja, dat is mogelijk als je verschillende class loaders gebruikt. Klassen met dezelfde FQDN, geladen door verschillende loaders, worden beschouwd als verschillende types voor de JVM.
Voorbeeld:
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
Verhaal
In een groot serversysteem werden plugins gebruikt, waarbij elke plugin via een aparte custom classloader werd aangesloten. De plugins wisselden objecten uit via een gemeenschappelijk interface, ook geladen door hun eigen classloader. Dit leidde tot ClassCastException bij typecasting, aangezien interface 'PluginApi' vanuit de plugin classloader en het hoofdsysteem als verschillende types werd beschouwd.
Verhaal
De poging tot "hot" herlaad van een servlet via een custom classloader leidde tot geheugenswapen - de oude klasse werd niet uit het geheugen verwijderd omdat er ergens een referentie in statische variabelen bleef. Dit resulteerde in een snelle overdracht van PermGen.
Verhaal
Een product met ondersteuning voor dynamische module loading gebruikte impliciet de systeem class loader, en ontwikkelaars vervingen per ongeluk de ouder, waardoor de toegang tot de basis klassen (bijvoorbeeld uit JDK) verloren ging. Dit leidde tot crashes wanneer de nieuwe module standaard Java-klassen, zoals
java.sql.Driver, niet kon laden.