mercoledì 26 marzo 2008

Alcune considerazioni sul caricamento delle classi

Java mette a disposizione dell'utente/programmatore due metodi principali per il caricamento di una classe:
  • l'utilizzo dei metodi statici definiti in java.lang.Class
  • l'utilizzo di un ClassLoader
In entrambi i casi è necessario conoscere il nome della classe che si vuole caricare dinamicamente. Le differenze fra l'utilizzo di Class.forName(..) e ClassLoader.loadClass(..) sono sostanzialmente le seguenti:
  • Class.forName(..) richiama tutti gli inizializzatori statici della classe caricata, mentre ClassLoader.loadClass(..) ritarda gli inizializzatori statici fino al momento in cui la classe non viene concretamente utilizzata;
  • l'utilizzo di un class loader consente una personalizzazione maggiore nel processo di caricamento delle classi;
  • l'utilizzo di ClassLoader.loadClass(..) memorizza la classe caricata nella cache del class loader che effettivamente carica la classe (che potrebbe essere un parent loader), mentre Class.forName(..) memorizza la classe nella cache del class loader corrente.
In generale, se occorre avere il controllo sul processo di risoluzione/caricamento di una classe, è necessario implementare tale controllo all'interno di uno specifico class loader.

Si tenga presente che molti application server (es. Tomcat, JBoss, ecc.) utilizzano un proprio schema di classloader al fine di fornire spazi protetti alle classi dell'utente e per consentire un hot-deployment delle stesse. Infatti, all'interno di una JVM una classe è univocamente identificata dal suo nome e dal class loader che l'ha caricata, ne consegue che fornendo un class loader per ogni applicazione all'interno di un container si può consentire l'esecuzione di più classi con lo stesso nome e comportamento differente. Inoltre, grazie all'uso di classloader separati (quindi con cache separati) è possibile caricare immediatamente la nuova versione di una applicazione senza bisogno di riavviare il container stesso.

Nessun commento: