ClassLoader es un componente especial en la JVM que se encarga de cargar el bytecode de las clases en memoria cuando se utilizan por primera vez. Permite cargar clases dinámicamente desde diversas fuentes (sistema de archivos, red, archivos comprimidos, etc.).
Tipos de cargadores de clases:
jre/lib/ext.ClassLoader implementa la delegación: primero intenta cargar la clase desde el cargador padre (parent-first), sólo si falla, busca por sí mismo.
Aislamiento de clases: Cada cargador de clases crea su "área de visibilidad" para las clases. Dos clases con el mismo nombre, cargadas por diferentes cargadores, se consideran tipos diferentes dentro de la JVM.
Ejemplo de creación de un cargador personalizado:
class MyClassLoader extends ClassLoader { @Override protected Class<?> findClass(String name) throws ClassNotFoundException { // Tu código para buscar y cargar el bytecode de la clase return super.findClass(name); } }
¿Pueden dos clases con el mismo nombre, cargadas por diferentes cargadores, considerarse una sola clase dentro de la JVM?
Respuesta: ¡No! La JVM considera que una clase es única por el par (nombre completo de la clase, cargador de clases). Por lo tanto, las mismas clases, cargadas por diferentes cargadores, se considerarán diferentes.
Historia
En una aplicación empresarial con soporte para arquitectura de plug-ins, los plug-ins se cargaban con cargadores de clases separados. Como resultado, intentar pasar un objeto del tipo interface (PluginInterface) entre la aplicación principal y el plug-in provocaba un ClassCastException, porque la misma interfaz fue cargada por diferentes cargadores.
Historia
Al usar un cargador de clases personalizado, no se implementó la delegación al cargador padre. Esto llevó a la recarga de clases estándar de la biblioteca, lo que causó extraños errores de ClassCastException y LinkageError.
Historia
En un gran servidor Java EE, diferentes aplicaciones cargaron sus versiones de la misma biblioteca. La negligencia en la configuración de la cadena de cargadores llevó a que las clases se cruzaran entre aplicaciones, lo que una vez causó una fuga masiva de memoria y fallos debido a conflictos de versiones.