En Java, las clases se cargan en memoria mediante objetos especiales llamados cargadores de clases (class loaders). Cada cargador de clases forma su propio espacio de visibilidad de clases.
Tipos de cargadores de clases:
$JAVA_HOME/lib/ext.Características:
¿Se puede cargar varias versiones de la misma clase en el proceso de la JVM, y cómo se puede hacer esto?
Respuesta: Sí, es posible si se utilizan diferentes cargadores de clases. Las clases con el mismo FQDN, cargadas por diferentes cargadores, se consideran diferentes tipos para la JVM.
Ejemplo:
ClassLoader loader1 = new URLClassLoader(new URL[]{...}); ClassLoader loader2 = new URLClassLoader(new URL[]{...}); Class clazz1 = loader1.loadClass("com.example.MyClass"); Class clazz2 = loader2.loadClass("com.example.MyClass"); System.out.println(clazz1 == clazz2); // false
Historia
En un gran sistema de servidor se usaban plugins, cada uno conectado a través de un cargador de clases personalizado. Los plugins intercambiaban objetos a través de una interfaz común, también cargada por su propio cargador de clases. Se producía un ClassCastException al convertir tipos, ya que la interfaz 'PluginApi' del cargador del plugin y el del sistema principal se consideraban tipos diferentes.
Historia
Un intento de "recarga en caliente" de un servlet a través de un cargador de clases personalizado provocó fugas de memoria: la clase antigua no se descargaba de la memoria, ya que había una referencia en alguna de las variables estáticas. Como resultado, el PermGen se llenaba rápidamente.
Historia
Un producto con soporte para carga dinámica de módulos usaba implícitamente el cargador de clases del sistema, y los desarrolladores accidentalmente reemplazaron su padre, perdiendo acceso a las clases base (por ejemplo, del JDK). Esto se manifestaba en caídas, cuando un nuevo módulo no podía cargar clases estándar de Java, como
java.sql.Driver.