ejemplo - classloader java example
Cargadores de clase Java (8)
¿Alguien puede indicarme un buen recurso o explicarme el concepto detrás de los cargadores de clase? Encontré el siguiente recurso en los cargadores de clases http://www.onjava.com/lpt/a/5586 pero aún no recibí ayuda. Las siguientes preguntas pueden parecer tontas, pero tratar de responderlas siempre me confunde.
- ¿Por qué los desarrolladores escriben cargadores de clases personalizados? ¿Por qué no invocar un cargador de clases Bootstrap para invocar sus clases personalizadas? ¿Cuál es la necesidad de definir cargadores de clase personalizados?
¿Por qué hay tantas variedades de cargadores de clase? por ejemplo: Bootsrap, Comman, cargador de clases Catalina, etc.
Gracias por adelantado.
¿Por qué los desarrolladores escriben cargadores de clases personalizados? ¿Por qué no invocar un cargador de clases Bootstrap para invocar sus clases personalizadas? ¿Cuál es la necesidad de definir cargadores de clase personalizados?
Dependiendo de la aplicación, los desarrolladores pueden anular o reemplazar completamente el mecanismo de carga de clases para satisfacer sus necesidades.
Por ejemplo, he usado una aplicación cuyas clases se cargan desde un LDAP: S
Otras aplicaciones necesitan administración de clase independiente (como la mayoría de los servidores de aplicaciones que admiten implementación en caliente)
Acerca de los recursos, hay TONELADAS, en la web, que simplemente no se pueden enumerar.
Encontré las siguientes razones válidas para crear classloaders personalizados:
Desea cargar una clase desde una fuente no convencional (por ejemplo, el bytecode para una clase se almacena en una base de datos, en la red o como 0 y 1 por pidgeons - MessengerPidgeonClassLoader). Ya hay algunas implementaciones de ClassLoader en la API para tales casos, como URLClassLoader .
Necesita definir una jerarquía diferente para cargar clases. Las implementaciones predeterminadas del ClassLoader delegan primero la búsqueda al padre, luego intentan cargar la clase ellos mismos. Tal vez quieras una jerarquía diferente. Esta es la razón por la cual OSGI y Eclipse tienen sus propios ClassLoaders, ya que los archivos .MF Manifest definen todos los tipos de rutas de jerarquía raras (por ejemplo, compilación de clases compiladas). Todos los cargadores de clase Eclipse implementan la interfaz BundleClassLoader y tienen un código adicional para encontrar recursos dentro de Eclipse Plugins.
Debes hacer algunas modificaciones al bytecode. Tal vez el bytecode está encriptado, y lo descifrarás sobre la marcha ( no es que sea útil, realmente, pero se ha intentado ). Tal vez quiera "aplicar parches" a las clases cargadas sobre la marcha (mejora del código de bytes A la JDO).
Se necesita usar un cargador de clases diferente del System Classloader si necesita descargar clases de la memoria o cargar clases que podrían cambiar su definición en el tiempo de ejecución. Un caso típico es una aplicación que genera una clase sobre la marcha desde un archivo XML, por ejemplo, y luego intenta volver a cargar esta clase. Una vez que una clase está en System Classloader, no hay forma de descargarla y tener una nueva definición.
Es extremadamente raro que necesite crear su propio ClassLoader. Y, en general, si es necesario, ya debería tener una comprensión muy buena de lo que hace el ClassLoader.
En otras palabras, si estás preguntando por qué necesitarías crear tu propio ClassLoader, entonces no necesitas crear uno;)
Una vez dicho esto, también he visto que se está creando un ClassLoader para una aplicación que se ocupa de la criptografía. De esta forma, cada vez que creas un java.netSocket o algún tipo de objeto de archivo / secuencia, en lugar de usar las versiones de JVM usaría sus propias clases especiales creadas a medida. De esta forma, podrían garantizar que toda la información esté encriptada y que no haya errores de desarrollador.
Pero no es muy común. Puede realizar toda una carrera en Java sin tener que crear su propio ClassLoader personalizado. En realidad, si necesita crear uno, realmente debería preguntar si es necesario.
Un par de blogs que escribí en el pasado sobre el uso de cargadores de clases post-delegación:
Un uso común de los cargadores de clases es aislar un JAR. Si tiene una aplicación que usa complementos ( Eclipse , Maven 2 ), entonces puede tener esta situación: el complemento X necesita el paquete A con la versión 1.0, mientras que el complemento Y necesita el mismo paquete pero la versión 2.0. X no se ejecuta con la versión 2.0, sin embargo.
Si tiene cargadores de clases, puede crear particiones de clases (piense en islas aisladas conectadas por puentes delgados, los puentes son los cargadores de clases). De esta forma, los classloaders pueden controlar lo que cada plugin puede ver.
Cuando el complemento X ejemplifica una clase Foo, que tiene campos estáticos, esto no es problema y no habrá una confusión con la "misma" clase en el complemento Y porque cada cargador de clases creará de hecho su propia instancia de la clase Foo. Luego tiene dos clases en la memoria, donde cl1.getName().equals(cl2.getName())
es true
pero cl1.equals(cl2)
no lo es. Esto significa que las instancias de cl1 no son compatibles con las instancias de cl2. Esto puede generar extrañas ClassCastExceptions
que dicen que org.project.Foo
no se puede asignar a org.project.Foo
.
Al igual que en las islas remotas, las dos clases no saben que existe la otra. Piense en los clones humanos que nacen y luego se crían en diferentes islas. Desde el punto de vista de la VM, no hay problema porque las instancias del tipo Class se manejan como cualquier otro objeto: puede haber varias de ellas. Que pienses que algunos de ellos son "lo mismo" no le importa a la VM.
Otro uso para este patrón es que puede deshacerse de las clases cargadas de esta manera: solo asegúrese de que nadie tenga un puntero a ningún objeto creado a partir de las clases cargadas desde un cargador de clases y luego olvídese también del cargador de clases. En la próxima ejecución del GC , todas las clases cargadas por este cargador de clases se eliminan de la memoria. Esto le permite "recargar" su aplicación sin tener que reiniciar toda la máquina virtual.
No puede ir más allá de la fuente cruda, en casos como este. Si realmente quieres la droga interna, el núcleo duro , lee los bits relevantes de la Especificación de Máquina Virtual de Java .
Otro buen enlace para cargadores de clase java - cargadores de clase Java
Un ejemplo:
Tomcat utiliza WebAppClassloader personalizado para cargar y aislar clases / jar de diferentes aplicaciones web.