El cargador de clases de Java es una parte del entorno de ejecución de Java que carga dinámicamente clases Java en la máquina virtual de Java . [1] Por lo general, las clases solo se cargan bajo demanda . El sistema de tiempo de ejecución de Java no necesita conocer archivos y sistemas de archivos, ya que esto se delega en el cargador de clases.
Una biblioteca de software es una colección de código objeto relacionado . En el lenguaje Java , las bibliotecas suelen estar empaquetadas en archivos JAR . Las bibliotecas pueden contener objetos de diferentes tipos. El tipo de objeto más importante contenido en un archivo Jar es una clase Java . Se puede pensar en una clase como una unidad de código con nombre. El cargador de clases es responsable de localizar bibliotecas, leer su contenido y cargar las clases contenidas dentro de las bibliotecas. Esta carga se realiza típicamente "a pedido", en el sentido de que no ocurre hasta que el programa llama a la clase. Una clase con un nombre dado solo puede ser cargada una vez por un cargador de clases dado.
Cada clase Java debe ser cargada por un cargador de clases. [2] Además, los programas Java pueden hacer uso de bibliotecas externas (es decir, bibliotecas escritas y proporcionadas por alguien que no sea el autor del programa) o pueden estar compuestos, al menos en parte, por varias bibliotecas.
Cuando se inicia la JVM, se utilizan tres cargadores de clases: [3] [4]
- Cargador de clases Bootstrap
- Cargador de clases de extensiones
- Cargador de clases de sistema
El cargador de clases de arranque carga las bibliotecas centrales de Java [fn 1] ubicadas en el
directorio. Este cargador de clases, que forma parte de la JVM principal, está escrito en código nativo.
El cargador de clases de extensiones carga el código en los directorios de extensiones (
, [3] o cualquier otro directorio especificado por la java.ext.dirs
propiedad del sistema).
El cargador de clases del sistema carga el código que se encuentra en java.class.path
, que se asigna a la CLASSPATH
variable de entorno .
Cargadores de clases definidos por el usuario
El cargador de clases de Java está escrito en Java. Por lo tanto, es posible crear su propio cargador de clases sin comprender los detalles más finos de la máquina virtual Java. Cada cargador de clases Java tiene un cargador de clases padre, definido cuando se crea una instancia de un nuevo cargador de clases o se configura en el cargador de clases predeterminado del sistema de la máquina virtual.
Esto hace posible (por ejemplo):
- para cargar o descargar clases en tiempo de ejecución (por ejemplo, para cargar bibliotecas dinámicamente en tiempo de ejecución, incluso desde un recurso HTTP ). Esta es una característica importante para:
- implementación de lenguajes de secuencias de comandos, como Jython
- usando constructores de frijoles
- permitiendo la extensibilidad definida por el usuario
- permitiendo que múltiples espacios de nombres se comuniquen. Esta es una de las bases de los protocolos CORBA / RMI , por ejemplo.
- para cambiar la forma en que se carga el código de bytes (por ejemplo, es posible utilizar el código de bytes de clase Java cifrado [5] ).
- para modificar el código de bytes cargado (por ejemplo, para el tejido de aspectos en tiempo de carga cuando se utiliza la programación orientada a aspectos ).
Cargadores de clases en Yakarta EE.
Los servidores de aplicaciones Jakarta EE (anteriormente Java EE y J2EE) normalmente cargan clases desde un archivo WAR o EAR implementado mediante un árbol de cargadores de clases, aislando la aplicación de otras aplicaciones, pero compartiendo clases entre módulos implementados. Los denominados " contenedores de servlets " se implementan normalmente en términos de cargadores de clases múltiples. [2] [6]
JAR infierno
El infierno de JAR es un término similar al infierno de DLL que se usa para describir todas las diversas formas en que el proceso de carga de clases puede terminar sin funcionar. [7] Tres formas en que puede ocurrir el infierno JAR son:
- Presencia accidental de dos versiones diferentes de una biblioteca instalada en un sistema. Esto no será considerado un error por el sistema. Más bien, el sistema cargará clases de una u otra biblioteca. Agregar la nueva biblioteca a la lista de bibliotecas disponibles en lugar de reemplazarla puede resultar en que la aplicación aún se comporte como si la biblioteca anterior estuviera en uso, lo que bien puede ser.
- Varias bibliotecas o aplicaciones requieren diferentes versiones de la biblioteca foo . Si las versiones de la biblioteca foo usan los mismos nombres de clase, no hay forma de cargar las versiones de la biblioteca foo con el mismo cargador de clases.
- Los problemas más complejos del infierno de JAR surgen en circunstancias que aprovechan toda la complejidad del sistema de carga de clases. No es necesario que un programa Java utilice un solo cargador de clases "plano", sino que puede estar compuesto por varios (potencialmente muchos) cargadores de clases cooperantes anidados. Las clases cargadas por diferentes cargadores de clases pueden interactuar de formas complejas que un desarrollador no comprende completamente, lo que lleva a errores o errores que son difíciles de analizar, explicar y resolver. [8]
La OSGi Alliance especificó (comenzando como JSR 8 en 1998) un marco de modularidad que tiene como objetivo resolver el infierno JAR para las VM actuales y futuras en ME, SE y EE que es ampliamente adoptado. Al usar metadatos en el manifiesto JAR , los archivos JAR (llamados paquetes) se conectan por paquete. Los paquetes pueden exportar paquetes, importar paquetes y mantener los paquetes privados, proporcionando las construcciones básicas de modularidad y gestión de dependencias versionadas.
Para remediar los problemas del infierno de JAR, en 2005 se inició un proceso de comunidad Java - JSR 277. La resolución - Sistema de módulo de plataforma Java - tenía como objetivo introducir un nuevo formato de distribución, un esquema de versiones de módulos y un repositorio de módulos común (similar en propósito a microsoft .NET 's Global Assembly Cache ). En diciembre de 2008, Sun anunció que JSR 277 estaba en espera. [9] El Java Module System se reinició más tarde como "proyecto Jigsaw" [10] que se incluyó en Java 9 .
Ver también
- Cargador (informática)
- Carga dinámica
- DLL infierno
- OSGi
- Ruta de clases (Java)
- Sistema de módulo de plataforma Java
Notas al pie
- ^ Estas bibliotecas se almacenan en archivos Jar llamados rt.jar , core.jar , server.jar , etc.
Referencias
- ^ Mcmanis, Chuck (1 de octubre de 1996). "Los fundamentos de los cargadores de clases de Java" . JavaWorld . Consultado el 13 de julio de 2020 .
- ^ a b Christudas, Binildas (26 de enero de 2005). "Internos de la carga de clases de Java" . onjava.com . Archivado desde el original el 10 de mayo de 2018.
- ^ a b "Comprensión de la carga de clases de extensión" . Los tutoriales de Java. docs.oracle.com . Consultado el 13 de julio de 2020 .
- ^ Sosnoski, Dennis (29 de abril de 2003). "Clases y carga de clases" . IBM DeveloperWorks . Consultado el 26 de enero de 2008 .
- ^ Roubtsov, Vladimir (9 de mayo de 2003). "Rompiendo el cifrado de código de bytes de Java" . JavaWorld . Consultado el 13 de julio de 2020 .
- ^ deBoer, Tim; Karasiuk, Gary (21 de agosto de 2002). "Carga de clase J2EE desmitificada" . IBM DeveloperWorks . Consultado el 26 de enero de 2008 .
- ^ https://web.archive.org/web/20130601002059/http://incubator.apache.org/depot/version/jar-hell.html
- ^ http://articles.qos.ch/classloader.html
- ^ Mark Reinhold (20 de septiembre de 2010). "Proyecto Jigsaw" . Oracle Corporation . Archivado desde el original el 8 de diciembre de 2015.
- ^ "Proyecto Jigsaw" . Oracle Corporation . Consultado el 29 de noviembre de 2015 .
enlaces externos
- Chuck McManis, " Los conceptos básicos de los cargadores de clases de Java ", 1996
- Brandon E. Taylor, " Carga de clases de Java: conceptos básicos ", 2003
- Jeff Hanson, " Tome el control de la carga de clases en Java ", 2006-06-01
- Andreas Schaefer, " Inside Class Loaders ", 12/11/2003
- Sheng Liang y Gilad Bracha, " Carga dinámica de clases en la máquina virtual Java ", en las actas de la 13ª Conferencia de ACM sobre programación, sistemas, lenguajes y aplicaciones orientadas a objetos (OOPSLA'98), avisos de ACM SIGPLAN, vol. 33, no. 10, ACM Press, 1998, págs. 36–44 doi : 10.1145 / 286936.286945
- Jeremy Whitlock, " Uso en el mundo real para cargadores de clases personalizados ", mayo de 2005
- Dr. Christoph G. Jung, " Implementación en caliente revisada de los cargadores de clases ", Boletín para especialistas en Java , 2007-06-07
- Don Schwarz, " Gestión de dependencias de componentes mediante ClassLoaders ", 2005-04-13