ProgrammatieSenior Java Backend ontwikkelaar

Hoe werkt de class loading mechanisme in Java, welke soorten class loaders bestaan er en welke mogelijke problemen kunnen zich voordoen bij verkeerd gebruik?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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:

  1. Bootstrap ClassLoader - laadt de basis klassen van JDK (rt.jar en dergelijke).
  2. Extension ClassLoader - laadt extensies uit $JAVA_HOME/lib/ext.
  3. System (Application) ClassLoader - laadt klassen uit de classpath van de applicatie.
  4. Custom ClassLoader - gebruikersdefinities loaders voor dynamische loading.

Kenmerken:

  • Een klasse wordt als uniek beschouwd binnen de combinatie (class loader, klassenaam).
  • Twee identieke klassen, geladen door verschillende loaders, worden als verschillend beschouwd.
  • Class loaders vormen een hiërarchie (ouder-kind).
  • Klassen kunnen geladen worden uit bytes (defineClass) - relevant voor plugins/JSP en dergelijke.

Misleidende vraag.

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

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp.


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.