# Java Classloader

El Java Class Loader és una part de l'entorn d'execució de Java que carrega dinàmicament classes de Java a la màquina virtual de Java. Normalment les classes només es carreguen sota demanda. La màquina virtual només carregarà els fitxers de classe necessaris per executar el programa. El sistema de temps d'execució de Java no necessita saber sobre fitxers i sistemes de fitxers, ja que això es delega al carregador de classes.
Una biblioteca de programari és una col·lecció de codi objecte relacionat. En el llenguatge Java, les biblioteques solen empaquetar-se en fitxers JAR. Les biblioteques poden contenir objectes de diferents tipus. El tipus d'objecte més important contingut en un fitxer Jar és una classe Java. Una classe es pot considerar com una unitat de codi anomenada. El carregador de classes és responsable de localitzar les biblioteques, llegir-ne el contingut i carregar les classes contingudes a les biblioteques. Aquesta càrrega normalment es fa "a demanda", ja que no es produeix fins que el programa crida la classe. Una classe amb un nom donat només es pot carregar una vegada per un carregador de classes determinat.
Quan s'inicia la JVM, s'utilitzen tres carregadors de classes:
* Carregador de classe Bootstrap
* Carregador de classes d'extensions
* Carregador de classes del sistema
El carregador de classes d'arrencada carrega les biblioteques bàsiques de Java ubicades al directori <JAVA_HOME>/jre/lib (o <JAVA_HOME>/jmods> per a Java 9 i superior). Aquest carregador de classes, que forma part de la JVM principal, està escrit en codi natiu. El carregador de classes boostrap no està associat amb cap objecte ClassLoader.
El carregador de classes d'extensions carrega el codi als directoris d'extensions (<JAVA_HOME>/jre/lib/ext, o qualsevol altre directori especificat per la propietat del sistema java.ext.dirs ).
El carregador de classes del sistema carrega el codi que es troba a java.class.path, que s'assigna a la variable d'entorn CLASSPATH.

## Carregadors de classes definits per l'usuari

El carregador de classes Java està escrit en Java. Per tant, és possible crear el vostre propi carregador de classes sense entendre els detalls més detallats de la màquina virtual de Java. A part del carregador de classes Bootstrap, cada carregador de classes Java té un carregador de classes pare. El carregador de classes pare es defineix quan s'instancia un carregador de classes nou o s'estableix al carregador de classes predeterminat del sistema de la màquina virtual.
Això fa possible (per exemple):
* per carregar o descarregar classes en temps d'execució (per exemple, per carregar biblioteques de manera dinàmica en temps d'execució, fins i tot des d'un recurs HTTP). Aquesta és una característica important per a:
** implementant llenguatges de script, com ara Jython
** utilitzant constructors de mongetes
** permetent una extensibilitat definida per l'usuari
** permetent que es comuniquin múltiples espais de noms. Aquest és un dels fonaments dels protocols CORBA/RMI, per exemple.
* per canviar la manera com es carrega el bytecode (per exemple, és possible utilitzar el bytecode de classe Java xifrat).
* per modificar el bytecode carregat (per exemple, per teixir aspectes en temps de càrrega quan s'utilitza programació orientada a aspectes).

## Carregadores de classe a Jakarta EE

Els servidors d'aplicacions de Jakarta EE (abans Java EE i J2EE) solen carregar classes des d'un arxiu WAR o EAR desplegat mitjançant un arbre de carregadors de classes, aïllant l'aplicació d'altres aplicacions, però compartint classes entre mòduls desplegats. Els anomenats " contenidors de servlets " solen implementar-se en termes de carregadors de classes múltiples.

### JAR infern

JAR Hell és un terme similar a DLL Hell que s'utilitza per descriure totes les maneres en què el procés de càrrega de classes pot acabar sense funcionar. Tres maneres en què l'infern JAR pot ocórrer són:
* Presència accidental de dues versions diferents d'una biblioteca instal·lada en un sistema. Això no es considerarà un error pel sistema. Més aviat, el sistema carregarà classes d'una o altra biblioteca. Afegir la biblioteca nova a la llista de biblioteques disponibles en lloc de substituir-la pot provocar que l'aplicació encara es comporti com si la biblioteca antiga estigués en ús, cosa que potser sí.
* Diverses biblioteques o aplicacions requereixen diferents versions de la biblioteca foo. Si les versions de la biblioteca foo utilitzen els mateixos noms de classe, no hi ha manera de carregar les versions de la biblioteca foo amb el mateix carregador de classes.
* Els problemes més complexos de l'infern JAR sorgeixen en circumstàncies que aprofiten tota la complexitat del sistema de càrrega de classes. Un programa Java no és necessari per utilitzar només un únic carregador de classes "pla", sinó que pot estar compost per diversos (potencialment molts) carregadors de classes que cooperen i imbricats. Les classes carregades per diferents carregadors de classes poden interactuar de maneres complexes que un desenvolupador no entén completament, provocant errors o errors difícils d'analitzar, explicar i resoldre.
L'OSGi Alliance va especificar (començant com a JSR 8 el 1998) un marc de modularitat que té com a objectiu resoldre l'infern JAR per a les VM actuals i futures a ME, SE i EE que s'adopta àmpliament. Si utilitzen metadades al manifest JAR, els fitxers JAR (anomenats paquets) es connecten per paquet. Els paquets poden exportar paquets, importar paquets i mantenir paquets privats, proporcionant les construccions bàsiques de modularitat i gestió de dependències versionades.

## Referències

* ↑ Mcmanis, Chuck. «The basics of Java class loaders» (en anglès). JavaWorld, 01-10-1996. [Consulta: 13 juliol 2020].
* 1 2 Horstmann, 2022, §10.1.1 The Class-Loading Process.
* ↑ «Understanding Extension Class Loading» (en anglès). docs.oracle.com. [Consulta: 13 juliol 2020].
* ↑ Sosnoski, Dennis. «Classes and class loading» (en anglès). IBM DeveloperWorks, 29-04-2003. [Consulta: 26 gener 2008].
* ↑ «Understanding Extension Class Loading» (en anglès). docs.oracle.com. [Consulta: 13 juliol 2020].
* ↑ Horstmann, 2022, 10.1.2 The Class Loader Hierarchy.
* ↑ Christudas, Binildas. «Internals of Java Class Loading» (en anglès). onjava.com, 26-01-2005. Arxivat de l'original el 2018-05-10.
* ↑ deBoer, Tim. «J2EE Class Loading Demystified» (en anglès). IBM DeveloperWorks, 21-08-2002. [Consulta: 26 gener 2008].
* ↑ «Depot - Apache Incubator» (en anglès). Arxivat de l'original el 2013-06-01.