Master D Labs – Blog profesional sobre TIC de Master D

Consejos a la hora de redactar para Internet

Escrito por master-d el Friday, 6 August, 2010

Escribir textos para Internet no es como escribir para otros medios como puede ser la prensa escrita, ya que además de tener claro cual es el mensaje que se quiere transmitir, (algo común para todos los medios), es imprescindible tener claros que otros objetivos se persiguen, como el posicionamiento de determinadas palabras clave y ofrecer [...]

Seguir leyendo

MasterD asiste al MadinSpain (MAD MMX) en Madrid

Escrito por master-d el Thursday, 8 July, 2010

Una vez más, hemos asistido al Congreso MadinSpain (MAD MMX) organizado por Domestika.org que se celebró en Madrid los días 2 y 3 de julio y que ha cumplido este año su quinta edición.
http://www.madinspain.com
Este evento congrega normalmente a los mejores creativos, agencias de publicidad, estudios de diseño y creadores de motion graphics del panorama actual, [...]

Seguir leyendo

Google Insights, utilizada por los profesionales de Master-D

Escrito por master-d el Wednesday, 9 June, 2010

Mejorar el posicionamiento de sus cursos y tener mayor visibilidad en la web es uno de los objetivos de Master-D.
Entre las herramientas, que utilizamos en Master-D, para mejorar el posicionamiento y con ello que nuestros contenidos, webs y cursos se posicionen mejor, tenemos Google Insight.
Google Insights es una herramienta gratuita desarrollada por Google que sirve [...]

Seguir leyendo

Nube de tags

Desmitificando los ClassLoaders de Java

Escrito por david peman el Thursday, 19 March, 2009

Cuando programamos en Java sabemos que nuestras clases se pueden ejecutar en distintas plataformas sin tener que modificarlas gracias a la existencia de la máquina virtual, pero no nos paramos a pensar como funciona esa sinergia entre clases y máquina virtual. ¿Cómo, Cuándo, Desde donde lee nuestras clases la JVM?. ¡¡¡La respuesta me la sé!!!, vaya pregunta mas fácil: desde el classpath que configuramos al arrancar la aplicación.

Pues sí, eso es parcialmente cierto, pero la respuesta no es tan obvia, ¿Qué pasa con los Applets?, ¿Y con Java Web Start?, ¿Por qué los servidores de aplicaciones como Tomcat, Jetty, JBoss, Glassfish, etc pueden permitirse el lujo de cargar las clases que dejamos en la carpeta WEB-INF/classes?. Esta sinergia totalmente personalizable entre clases y maquina virtual existe gracias a los ClassLoaders. Entonces…

¿Qué es un ClassLoader?

Un ClassLoader es una instancia de java.lang.ClassLoader responsable de cargar clases en memoria de una determinada manera, bajo demanda de la JVM.

Para la máquina virtual una clase se identifica por su nombre completo paquetex.paquetey.Clase y su ClassLoader. De está manera la clase es.masterd.SoyUnaClase cargada con el cargador MasterDClassLoaderCommon no es la misma clase que es.masterd.SoyUnaClase cargada con el cargador MasterDClassLoaderApplication.

Por defecto y en la mayoría de los casos, la máquina virtual carga las clases definidas en el classpath por medio del System ClassLoader. Pero nosotros podemos utilizar otro ClassLoader o incluso implementar uno nuevo y cargar las clases, por ejemplo, desde una URL remotamente.

Si nos paramos a pensar un momento, podemos intuir que aparte de ofrecerte un potencial enorme también te ofrece un grave fallo de seguridad. Podría programarme una clase maliciosa java.util.ArrayList diferente a la ya implementada en la JDK, inyectarla en el classpath y modificar su comportamiento a mi favor. Pero como ya sabemos, esto no pasa. ¿Por qué?.

Módelo de delegación de ClassLoaders

Existen tres ClassLoaders por defecto en Java:

- Bootstrap ClassLoader: Carga las clases principales de java como java.*, javax.*. Está implementado en C para cada plataforma, forma parte de la JVM.
- Extension ClassLoader: Carga las clases proporcionadas en el directorio de extensiones del JRE.
- System ClassLoader: También llamado comúnmente Application ClassLoader, carga las clases definidas en el classpath, las nuestras.

Cada ClassLoader contiene la referencia de su ClassLoader padre, formando así una Jerarquía de árbol, excepto Bootstrap ClassLoader que es la raíz del árbol. Por defecto, el padre de un ClassLoader implementado por nosotros es System ClassLoader pudiendo cambiarlo al que más nos interese. Aquí muestro un ejemplo visual de una Jerarquía de ClassLoaders:

Jerarquía classloaders por defecto

Los ClassLoaders, por defecto, delegan siempre la carga de la clase a su padre, recursivamente hasta llegar al Bootstrap ClassLoader, el origen de todos los ClassLoaders. Comprueba si ya está cargada y si no lo está, la intenta cargar. Si no puede la devuelve a su hijo, invirtiendo el proceso, hasta que un ClassLoader la cargue. Si ningún ClassLoader puede cargar la clase se lanzará la excepción java.lang.ClassNotFoundException.

De esta manera, se evita la sustitución maliciosa de clases base de la JRE. Aunque inyectáramos un java.util.ArrayList distinto en nuestro classpath, System ClassLoader delegará la carga a Extension ClassLoader y este a su vez la delegará a Bootstrap ClassLoader que encontrará que ya tiene una clase cargada con ese nombre (la original)  y no cargará la clase mal intencionada. El siguiente código de la clase java.lang.ClassLoader lo explica perfectamente.

Hecha la ley, hecha la trampa. Cuando programas un ClassLoader personalizado es recomendable usar este módelo basado en delegación, pero puedes no hacerlo. En este caso deberías asegurarte que si es una clase de sistema, se cargue con el System ClassLoader para evitar problemas. Existe un claro ejemplo que no usa el módelo de delegación: Los servidores de aplicaciones web. Ya que así lo recomienda la especificación de Java Servlet.

Todo esto está muy bien, pero me surge una duda…

¿Para qué me sirve programar un ClassLoader?

Se suele programar un ClassLoader en Java para poder obtener una clase de una forma distinta a la normal. Permiten hacer cosas como:

- Cargar y Descargar clases dinámicamente cuando se detecta un cambio.

- Ejecutar lenguajes de script.

- Implementar un sistema de plugins en tiempo de ejecución.

- Cargar las clases remotamente, por ejemplo, desde un LDAP.

- Cargar clases cifradas.

- Modificar el bytecode de la clase en tiempo de carga. Programación Orientada a Aspectos.

- Crear una jerarquía de cargadores, para aislar distintas aplicaciones en una misma JVM.

Conclusión

Los arquitectura de ClassLoaders de Java ofrece a los programadores una tremenda flexibilidad para extender y ensamblar nuestras aplicaciones. Por eso, un desarrollador Java debería entender la carga de clases al detalle. En este artículo se ha realizado una  introducción a los conceptos básicos de los ClassLoaders.

En mi siguiente post explicaré como programar un ClassLoader a medida. En este post hay mucha teoría, necesaria por otra parte, y como se entiende mejor los conceptos  es con un ejemplo práctico.

Saludos.

Posteado en: programador-aplicaciones, programador-web.

4 Responses to “Desmitificando los ClassLoaders de Java”

  1. gimenete Says:

    He visto utilizar class loaders para algunas cosas que comentas: cifrar clases y cargar plugins. Lo de cifrar las clases tiene su problema: que el ClassLoader que carga las clases cifradas no puede estar cifrado :P Pero bueno, siempre es una barrera más de seguridad. Nada es seguro 100%

    Muy buen artículo!

  2. MrMx Says:

    Muy bien explicado, pondré un ejemplo de classloader que hice hace tiempos para empaquetar una aplicación con las clases que solo necesita. Hoy en día lo haríamos con un ofuscador (yguard,etc), pero si controlamos todas las clases necesarias y todos los casos de uso, obtendríamos un nuevo jar con solo las dependencias indispensables.

    Un saludo! ;)

  3. Alex Says:

    Hola,

    estaría muy interesado en saber como descargar un JAR del SystemClassLoader.

    Los cargo correctamente (addURL) y todo va bien, pero me interesaría poder descargarlos luego y no encuentro la forma.

    Me podeis ayudar?

    gracias

  4. Inguelberth Says:

    hey, muy bien explicado, mis agracedimientos porque esto me a ayudado a comprender mejor eso del classLoader, voy a estar antento al otro post, y sino porfavor avisenme…

Leave a Reply