Caricatore classi Java - Java Classloader

Il Java Class Loader è una parte del Java Runtime Environment che carica dinamicamente le classi Java nel Java Virtual Machine . Di solito le classi vengono caricate solo su richiesta . Il sistema runtime Java non ha bisogno di conoscere file e file system poiché questo è delegato al caricatore di classi.

Una libreria software è una raccolta di codice oggetto correlato . Nel linguaggio Java , le librerie sono in genere impacchettate in file JAR . Le biblioteche possono contenere oggetti di diverso tipo. Il tipo più importante di oggetto contenuto in un file Jar è una classe Java . Una classe può essere pensata come un'unità di codice denominata. Il caricatore di classi è responsabile dell'individuazione delle librerie, della lettura dei loro contenuti e del caricamento delle classi contenute nelle librerie. Questo caricamento viene in genere eseguito "su richiesta", in quanto non si verifica finché la classe non viene chiamata dal programma. Una classe con un determinato nome può essere caricata solo una volta da un determinato caricatore di classi.

Ogni classe Java deve essere caricata da un caricatore di classi. Inoltre, i programmi Java possono fare uso di librerie esterne (cioè librerie scritte e fornite da qualcuno diverso dall'autore del programma) oppure possono essere composti, almeno in parte, da più librerie.

Quando viene avviata la JVM, vengono utilizzati tre caricatori di classe:

  1. Caricatore di classe Bootstrap
  2. Caricatore di classi di estensioni
  3. Caricatore di classi di sistema

Il caricatore di classi bootstrap carica le librerie Java principali che si trovano nella <JAVA_HOME>/jre/libdirectory. Questo caricatore di classi, che fa parte della JVM principale, è scritto in codice nativo.

Il caricatore della classe delle estensioni carica il codice nelle directory delle estensioni ( <JAVA_HOME>/jre/lib/ext, o in qualsiasi altra directory specificata dalla java.ext.dirsproprietà di sistema).

Il caricatore di classi di sistema carica il codice trovato su java.class.path, che mappa alla CLASSPATH variabile di ambiente .

Caricatori di classi definiti dall'utente

Il caricatore di classi Java è scritto in Java. È quindi possibile creare il proprio caricatore di classi senza comprendere i dettagli più fini della Java Virtual Machine. Ogni programma di caricamento classi Java ha un programma di caricamento classi padre, definito quando viene istanziato un nuovo programma di caricamento classi o impostato sul programma di caricamento classi predefinito del sistema della macchina virtuale.

Ciò rende possibile (ad esempio):

  • per caricare o scaricare classi in fase di esecuzione (ad esempio per caricare librerie in modo dinamico in fase di esecuzione, anche da una risorsa HTTP ). Questa è una caratteristica importante per:
    • implementare linguaggi di scripting, come Jython
    • usando i costruttori di fagioli
    • consentendo l' estensibilità definita dall'utente
    • permettendo a più namespace di comunicare. Questo è uno dei fondamenti dei protocolli CORBA / RMI , ad esempio.
  • per modificare la modalità di caricamento del bytecode (ad esempio, è possibile utilizzare un bytecode di classe Java crittografato ).
  • per modificare il bytecode caricato (ad esempio, per l' intreccio di aspetti nel tempo di caricamento quando si utilizza la programmazione orientata agli aspetti ).

Caricatori di classe a Jakarta EE

I server delle applicazioni Jakarta EE (precedentemente Java EE e J2EE) caricano in genere le classi da un archivio WAR o EAR distribuito mediante un albero di caricatori di classi, isolando l'applicazione da altre applicazioni, ma condividendo le classi tra i moduli distribuiti. I cosiddetti " contenitori servlet " sono tipicamente implementati in termini di caricatori di classi multiple.

VASO inferno

JAR hell è un termine simile a DLL hell usato per descrivere tutti i vari modi in cui il processo di caricamento delle classi può finire per non funzionare. Tre modi in cui può verificarsi l'inferno JAR sono:

  • Presenza accidentale di due diverse versioni di una libreria installata su un sistema. Questo non sarà considerato un errore dal sistema. Piuttosto, il sistema caricherà le classi dall'una o dall'altra libreria. L'aggiunta della nuova libreria all'elenco delle librerie disponibili invece di sostituirla potrebbe far sì che l'applicazione continui a comportarsi come se la vecchia libreria fosse in uso, il che potrebbe benissimo essere.
  • Più librerie o applicazioni richiedono versioni diverse della libreria foo . Se le versioni della libreria foo usano gli stessi nomi di classe, non c'è modo di caricare le versioni della libreria foo con lo stesso caricatore di classi.
  • I problemi dell'inferno JAR più complessi sorgono in circostanze che sfruttano l'intera complessità del sistema di caricamento delle classi. Non è necessario che un programma Java utilizzi solo un singolo caricatore di classi "piatto", ma può invece essere composto da diversi (potenzialmente moltissimi) caricatori di classi nidificati e cooperanti. Le classi caricate da diversi caricatori di classi possono interagire in modi complessi non completamente compresi da uno sviluppatore, portando a errori o bug difficili da analizzare, spiegare e risolvere.

L' OSGi Alliance ha specificato (a partire da JSR 8 nel 1998) un framework di modularità che mira a risolvere l'inferno JAR per le VM attuali e future in ME, SE ed EE ampiamente adottato. Utilizzando i metadati nel manifest JAR , i file JAR (chiamati bundle) vengono cablati in base al pacchetto. I bundle possono esportare pacchetti, importare pacchetti e mantenere i pacchetti privati, fornendo i costrutti di base della modularità e della gestione delle dipendenze con versione.

Per rimediare ai problemi dell'inferno JAR,  nel 2005 è stato avviato un Java Community Process — JSR 277. La risoluzione — Java Platform Module System  — intendeva introdurre un nuovo formato di distribuzione, uno schema di versioning dei moduli e un repository di moduli comune (simile nello scopo a Microsoft .NET s' Global Assembly cache ). Nel dicembre 2008, Sun ha annunciato che JSR 277 era stato sospeso. Il Java Module System è stato successivamente riavviato come "progetto Jigsaw" che è stato incluso in Java 9 .

Guarda anche

Note a piè di pagina

Riferimenti

link esterno