0 penilaian0% menganggap dokumen ini bermanfaat (0 suara)
84 tayangan113 halaman
This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3. Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. And provide a link to the original.
This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3. Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. And provide a link to the original.
This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3. Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. And provide a link to the original.
Platform 5 Manual del usuario de JBoss Microcontainer para uso con JBoss Enterprise Application Platform 5 Edicin 5.1.0 JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer para uso con JBoss Enterprise Application Platform 5 Edicin 5.1.0 Mark Newton Red Hat mark.newton@jboss.org Ale Justin Red Hat ajustin@redhat.com Edited by Misty Stanley-Jones Red Hat misty@redhat.com Legal Notice Copyright 2011 Red Hat, Inc. This document is licensed by Red Hat under the Creative Commons Attribution-ShareAlike 3.0 Unported License. If you distribute this document, or a modified version of it, you must provide attribution to Red Hat, Inc. and provide a link to the original. If the document is modified, all Red Hat trademarks must be removed. Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law. Red Hat, Red Hat Enterprise Linux, the Shadowman logo, JBoss, MetaMatrix, Fedora, the Infinity Logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries. Linux is the registered trademark of Linus Torvalds in the United States and other countries. Java is a registered trademark of Oracle and/or its affiliates. XFS is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries. MySQL is a registered trademark of MySQL AB in the United States, the European Union and other countries. Node.js is an official trademark of Joyent. Red Hat Software Collections is not formally related to or endorsed by the official Joyent Node.js open source or commercial project. The OpenStack Word Mark and OpenStack Logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community. All other trademarks are the property of their respective owners. Abstract Este manual est dirigido a aquellos desarrolladores Java que desean utilizar el microcontenedor JBoss para implementar entornos Java modulares y personalizados para sus aplicaciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Table of Contents Prefacio 1. Convenciones del Documento 1.1. Convenciones tipogrficas 1.2. Convenciones del documento 1.3. Notas y Advertencias 2. Cmo obtener ayuda y hacer sus comentarios 2.1. Necesita ayuda? 2.2. Necesitamos sus comentarios! Parte I. Introduccin al tutorial sobre el Microcontainer Captulo 1. Prerequisitos para el uso de este manual 1.1. Instale Maven 1.2. Configuracin especial de Maven para los ejemplos del microcontenedor 1.3. Descarga de los ejemplos Captulo 2. Introduccin al microcontenedor 2.1. Funcionalidades 2.2. Definiciones 2.3. Instalacin Captulo 3. Construccin de servicios 3.1. Introduccin al ejemplo de recusos humanos 3.2. Compilacin del proyecto de ejemplo HRManager 3.3. Creacin de POJOs 3.3.1. Descriptores de implementacin XML 3.4. Conexin de POJOs 3.4.1. Consideraciones especiales 3.5. Trabajar con servicios 3.5.1. Configuracin de un servicio 3.5.2. Probar un servicio 3.5.3. Empacar un servicio Captulo 4. Uso de los servicios 4.1. Bootstrap del microcontenedor 4.2. Implementacin del servicio 4.3. Acceso directo 4.4. Acceso indirecto 4.5. Carga de clase dinmica 4.5.1. Problemas con cargadores de clase creados con los descriptores de implementacin Captulo 5. Agregar comportamiento con AOP 5.1. Creacin de un aspecto 5.2. Configuracin del microcontenedor para AOP 5.3. Aplicacin de un aspecto 5.4. Callbacks del ciclo de vida 5.5. Agregar bsquedas de servicios por medio de JNDI Parte II. Conceptos avanzados con el microcontenedor Captulo 6. Modelos de componentes 6.1. Interacciones permitidas con los modelos de componentes 6.2. Un Bean sin dependencias 6.3. Uso del microcontenedor con Spring 4 4 4 5 6 6 6 7 8 9 9 12 13 14 14 14 15 16 16 17 17 17 17 18 18 19 19 21 23 26 27 28 30 31 36 37 37 39 41 43 45 47 48 48 48 48 Table of Contents 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3. Uso del microcontenedor con Spring 6.4. Uso de Guice con el microcontenedor 6.5. MBeans de legado y mezcla de diferentes modelos de componentes 6.6. Exponer POJOs como MBeans Captulo 7. Inyeccin avanzada de dependencias y ldC 7.1. Fbrica de valores 7.2. Callbacks 7.3. Modo de acceso del Bean 7.4. Alias Bean 7.5. Soporte para anotaciones XML (o metadatos) 7.6. Autowire 7.7. Fbrica de beans 7.8. Constructor de metadatos Bean 7.9. ClassLoader personalizado 7.10. Modo controlador 7.11. Ciclo 7.12. Oferta y demanda 7.13. Instalaciones 7.14. Imitacin perezosa 7.15. Ciclo de vida Captulo 8. El sistema virtual de archivos 8.1. API pblica VFS 8.2. Arquitectura VFS 8.3. Implementaciones existentes 8.4. Ganchos de extensin 8.5. Funcionalidades Captulo 9. La capa ClassLoading 9.1. ClassLoader 9.2. ClassLoading 9.3. Carga de clase VFS Captulo 10. Marco de trabajo de la implementacin virtual 10.1. Manejo agnstico de tipos de implementacin 10.2. Separacin del reconocimiento de la estructura de la lgica del ciclo de vida de la implementacin 10.3. Control de flujo natural en forma de anexos 10.4. Detalles de la implementacin y del cliente, usuario y uso del servidor 10.5. Mquina de estado nico 10.6. Escaneo de clases en busca de anotaciones Historial de revisiones 48 49 52 53 56 56 58 60 61 61 64 64 67 68 69 70 71 71 72 73 74 77 86 86 87 87 89 89 96 101 103 103 103 106 107 108 108 110 JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 2 Table of Contents 3 Prefacio 1. Convenciones del Documento Este manual utiliza varias convenciones para resaltar algunas palabras y frases y llamar la atencin sobre ciertas partes especficas de informacin. En ediciones PDF y de papel, este manual utiliza tipos de letra procedentes de Liberation Fonts. Liberation Fonts tambin se utilizan en ediciones de HTML si estn instalados en su sistema. Si no, se muestran tipografas alternativas pero equivalentes. Nota: Red Hat Enterprise Linux 5 y siguientes incluyen Liberation Fonts predeterminadas. 1.1. Convenciones tipogrficas Se utilizan cuatro convenciones tipogrficas para llamar la atencin sobre palabras o frases especficas. Dichas convenciones y las circunstancias en que se aplican son las siguientes: Negrita monoespaciado Utilizado para resaltar la entrada del sistema, incluyendo los comandos de shell, nombres de archivos y rutas. Tambin sirve para resaltar teclas y combinaciones de teclas. Por ejemplo: Para ver el contenido del archivo my_next_bestselling_novel en su directorio actual de trabajo, escriba el comando cat my_next_bestselling_novel en el intrprete de comandos de shell y pulse Enter para ejecutar el comando. El ejemplo anterior incluye un nombre de archivo, un comando de shell y una tecla . Todo se presenta en negrita-monoespaciado y distinguible gracias al contexto. Las combinaciones de teclas se pueden distinguir de las individuales con el signo ms que conecta cada partee de la combinacin de tecla. Por ejemplo: Pulse Enter para ejecutar el comando. Pulse Ctrl+Alt+F2 para pasar a una terminal virtual. El primer ejemplo resalta una tecla particular a pulsar. El segundo ejemplo, resalta una combinacin de teclas: un set de tres teclas pulsadas simultneamente. Si se discute el cdigo fuente, los nombres de las clase, los mtodos, las funciones, los nombres de variables y valores de retorno mencionados dentro de un prrafo sern presentados en Negrita- monoespaciado. Por ejemplo: Las clases de archivo relacionadas incluyen filename para sistema de archivos, file para archivos y dir para directorios. Cada clase tiene su propio conjunto asociado de permisos. Negrita proporcional Esta denota palabras o frases encontradas en un sistema, incluyendo nombres de aplicacin, texto de cuadro de dilogo, botones etiquetados, etiquetas de cajilla de verificacin y botn de radio; ttulos de men y ttulos del submen. Por ejemplo: Seleccione Sistema Preferencias Ratn desde la barra del men principal para lanzar Preferencias de ratn. En la pestaa de Botones, seleccione la cajilla de ratn JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 4 de mano izquierda y luego haga clic en Cerrar para cambiar el botn principal del ratn de la izquierda a la derecha (adecuando el ratn para la mano izquierda). Para insertar un carcter especial en un archivo gedit, seleccione Aplicaciones Accesorios Mapa de caracteres de la barra del men. Luego, seleccione Bsqueda Buscar de la barra del men de Mapa de caracteres, escriba el nombre del carcter en el campo de Bsqueda y haga clic en Siguiente. El carcter que busc ser resaltado en la Tabla de caracteres. Haga doble clic en ese carcter resaltado para colocarlo en el campo de Texto a copiar y luego haga clic en el botn Copiar. Ahora regrese al documento y elija Modificar Pegar de la barra de men de gedit. El texto anterior incluye nombres de aplicacin; nombres y elementos del men de todo el sistema; nombres de men de aplicaciones especficas y botones y texto hallados dentro de una interfaz grfica de usuario, todos presentados en negrita proporcional y distinguibles por contexto. Itlicas-negrita monoespaciado o Itlicas-negrita proporcional Ya sea negrita monoespaciado o negrita proporcional, la adicin de itlicas indica texto reemplazable o variable. Las itlicas denotan texto que usted no escribe literalmente o texto mostrado que cambia dependiendo de la circunstancia. Por ejemplo: Para conectar a una mquina remota utilizando ssh, teclee ssh nombre de usuario@dominio.nombre en un intrprete de comandos de shell. Si la mquina remota es example.com y su nombre de usuario en esa mquina es john, teclee ssh john@example.com. El comando mount -o remount file-system remonta el sistema de archivo llamado. Por ejemplo, para volver a montar el sistema de archivo /home, el comando es mount -o remount /home. Para ver la versin de un paquete actualmente instalado, utilice el comando rpm -q paquete. ste entregar el resultado siguiente: paquete-versin-lanzamiento. Observe que las palabras resaltadas en itlicas nombre de usuario, dominio.nombre, sistema de archivo, paquete, versin y lanzamiento. Cada palabra es un marcador de posicin, ya sea de texto a ingresar cuando se ejecuta un comando o para un texto ejecutado por el sistema. Aparte del uso estndar para presentar el ttulo de un trabajo, las itlicas denotan el primer uso de un trmino nuevo e importante. Por ejemplo: Publican es un sistema de publicacin de DocBook. 1.2. Convenciones del documento Los mensajes de salida de la terminal o fragmentos de cdigo fuente se distinguen visualmente del texto circundante. Los mensajes de salida enviados a una terminal se muestran en romano monoespaciado y se presentan as: books Desktop documentation drafts mss photos stuff svn books_tests Desktop1 downloads images notes scripts svgs Los listados de cdigo fuente tambin se muestran en romano monoespaciado, pero se presentan y resaltan de la siguiente manera: Prefacio 5 package org.jboss.book.jca.ex1; import javax.naming.InitialContext; public class ExClient { public static void main(String args[]) throws Exception { InitialContext iniCtx = new InitialContext(); Object ref = iniCtx.lookup("EchoBean"); EchoHome home = (EchoHome) ref; Echo echo = home.create(); System.out.println("Created Echo"); System.out.println("Echo.echo('Hello') = " + echo.echo("Hello")); } } 1.3. Notas y Advertencias Finalmente, utilizamos tres estilos visuales para llamar la atencin sobre la informacin que de otro modo se podra pasar por alto. Nota Una nota es una sugerencia, atajo o enfoque alternativo para una tarea determinada. Ignorar una nota no debera tener consecuencias negativas, pero podra perderse de algunos trucos que pueden facilitarle las cosas. Importante Los cuadros con el ttulo de importante dan detalles de cosas que se pueden pasar por alto fcilmente: cambios de configuracin nicamente aplicables a la sesin actual, o servicios que necesitan reiniciarse antes de que se aplique una actualizacin. Ignorar estos cuadros no ocasionar prdida de datos, pero puede causar enfado y frustracin. Aviso Las advertencias no deben ignorarse. Ignorarlas muy probablemente ocasionar prdida de datos. 2. Cmo obtener ayuda y hacer sus comentarios 2.1. Necesita ayuda? Si encuentra dificultades con alguno de los procedimientos descritos en este documento, visite el Portal del cliente de Red Hat en http://access.redhat.com. A travs del portal del cliente, usted podr: JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 6 buscar o navegar a travs de la base de artculos de soporte tcnico sobre productos de Red Hat. enviar un caso de soporte a Servicios de Soporte Global de Red Hat (GSS) acceder a otra documentacin del producto. Red Hat alberga una lista grande de correos electrnicos para discutir sobre software de Red Hat y tecnologa. Encontrar un listado de las listas de correo disponibles al pblico en https://www.redhat.com/mailman/listinfo. Haga clic en el nombre de la lista a la que quiera suscribirse o para acceder a los archivos de listados. 2.2. Necesitamos sus comentarios! Si encuentra algun error o si se le ocurre una manera de mejorar este manual, nos encantara escuchar sus sugerencias. Complete un reporte en Bugzilla frente al producto JBoss Enterprise Application Platform 5 y el componente doc-JBoss_Microcontainer_User_Guide. El siguiente enlace le llevar a un reporte de error ya completado para este producto: http://bugzilla.redhat.com/. Llene la siguiente plantilla en el campo de Description de Bugzilla. Sea tan especifico como le sea posible al describir el problema, esto ayudar a asegurarnos de que lo podemos solucionar rpidamente. URL del documento: Nmero de la seccin y nombre: Describa el problema: Sugerencias para mejorar: Informacin adicional: Asegrese de darnos su nombre para poder darle todo el crdito por reportar el problema. Prefacio 7 Parte I. Introduccin al tutorial sobre el Microcontainer JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 8 Captulo 1. Prerequisitos para el uso de este manual Para poder utilizar los ejemplos en este manual es necesario instalar y configurar el software de soporte y debe descargar el cdigo para los ejemplos. 1.1. Instale Maven Los ejemplos utilizados en este proyecto requieren Maven v2.2.0 o posteriores. Descargue Maven directamente de la pgina de inicio de Apache Maven e instale y configure su sistema tal como se describe en Procedimiento 1.1, Instale Maven. Procedimiento 1.1. Instale Maven 1. Verifique que tiene instalado Java Developer Kit 1.6 o posteriores. Este tambin es un requerimiento para la plataforma empresarial. Asegrese de que tiene instalado Java en su sistema y configure la variable de entorno JAVA_HOME en su ~/.bash_profile para Linux o en las propiedades del sistema para Windows. Para mayor informacin con relacin a la configuracin de las variables de entorno, consulte el paso Paso 4 en este procedimiento. 2. Descargue Maven Nota Este paso y en el futuro se asume que ha guardado Maven en la ubicacin sugerida en su sistema operativo. Maven, como cualquier otra aplicacin Java se puede instalar en cualquier lugar razonable en su sistema. Visite http://maven.apache.org/download.html. Haga clic en el enlace de fichero zip compilado, por ejemplo apache-maven-2.2.1-bin.zip Seleccione un espejo de descarga de la lista. Para usuarios de Linux Guarde el fichero zip en su directorio home. Para usuarios de Windows Guarde el fichero zip en su directorio C:\Documents and Settings\user_name. 3. Instale Maven Para usuarios de Linux Extraiga el archivo zip en su directorio home. Si seleccion el fichero zip en el paso 2 y no vuelve a nombrar el directorio, el directorio extrado se llama apache-maven-version. Para usuarios de Windows Extraiga el fichero zip en C:\Program Files\Apache Software Foundation. Si seleccion el fichero zip en el paso 2 y no vuelve a nombrar el directorio, el directorio extrado se llama apache- maven-version. 4. Configure las variables del entorno Captulo 1. Prerequisitos para el uso de este manual 9 Para usuarios de Linux Agregue las siguientes lneas a su ~/.bash_profile. Asegrese de cambiar el [username] a su nombre de usuario real y verifique que el directorio Maven es de hecho el nombre del directorio. El nmero de la versin puede ser diferente del que se lista a continuacin. export M2_HOME=/home/[username]/apache-maven-2.2.1 export M2=$M2_HOME/bin export PATH=$M2:$PATH Al incluir M2 al comienzo de su ruta, la versin Maven que acab de instalar ser la versin predeterminada utilizada. Puede que tambin quierar establecer la ruta de su variable de entorno JAVA_HOME con la ubicacin del JDK en su sistema. Para usuarios de Windows Agregue las variables de entorno M2_HOME, M2 y JAVA_HOME. a. Oprima Start+Pause|Break. Se presenta la ventana de propiedades del sistema. b. Haga clic en la pestaa Advanced y luego haga clic en el botn Environment Variables. c. Bajo System Variables, seleccione Path. d. Haga clic en Edit y agregue las dos rutas Maven usando un punto y coma para separar cada entrada. No se requieren comillas alrededor de las rutas. Agregue la variable M2_HOME y establezca la ruta como C:\Program Files\Apache Software Foundation\apache-maven-2.2.1. Agregue la variable M2 y configure el valor como %M2_HOME%\bin. e. En la misma ventana, cree la variable de entorno JAVA_HOME: Agregue la variable %JAVA_HOME% y establezca el valor con la ubicacin de su JDK. Por ejemplo C:\Program Files\Java\jdk1.6.0_02. f. En la misma ventana actualice o cree la variable de entorno de la ruta: Agregue la variable %M2% para permitir que se ejecute Maven desde la lnea de comandos. Agregue la variable %JAVA_HOME%\bin para establecer la ruta con la instalacin correcta de Java. g. Haga clic en OK hasta que la ventana System Properties se cierre. 5. Implemente los cambios en .bash_profile Solo para los usuarios de Linux Para actualizar los cambios realizados al .bash_profile en la sesin de la terminal actual proporcione su .bash_profile. [localhost]$ source ~/.bash_profile 6. Update gnome-terminal profile Solo para los usuarios de Linux Actualice el perfil de la terminal para asegurarse de que las iteraciones posteriores de la terminal gnome (o la terminal Konsole) lean las nuevas variables de entorno. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 10 a. Haga clic en Edit Profiles b. Seleccione Default y luego haga clic en el botn Edit. c. En la ventana Editing Profile, haga clic en la pestaa Title and Command. d. Seleccione la opcin Run command as login shell. e. Cierre todas las terminales que tenga abiertas. 7. Verifique los cambios en las variables de entorno y en la instalacin de Maven Para usuarios de Linux Para verificar que los cambios se han implementado correctamente, abra una terminal y ejecute los siguientes comandos: Ejecute echo $M2_HOME, el cual debe retornar el siguiente resultado. [localhost]$ echo $M2_HOME /home/username/apache-maven-2.2.1 Ejecute echo $M2, el cual debe retornar el siguiente resultado. [localhost]$ echo $M2 /home/username/apache-maven-2.2.1/bin Ejecute echo $PATH y verifique que el directorio Maven /bin est includo. [localhost]$ echo $PATH /home/username/apache-maven-2.2.1/bin Ejecute which mvn, el cual debe presentar la ruta al Maven ejecutable. [localhost]$ which mvn ~/apache-maven-2.2.1/bin/mvn Ejecute mvn -version, la cual debe presentar la versin de Maven, la versin Java relacionada y la informacin relacionada con el sistema operativo. [localhost]$ $ mvn -version Apache Maven 2.2.1 (r801777; 2009-08-07 05:16:01+1000) Java version: 1.6.0_0 Java home: /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre Default locale: en_US, platform encoding: UTF-8 OS name: "Linux" version: "2.6.30.9-96.fc11.i586" arch: "i386" Family: "unix" Para usuarios de Windows Para verificar que los cambios se han implementado correctamente, abra una terminal y ejecute el siguiente comando: En una lnea de comandos ejecute mvn -version C:\> mvn -version Apache Maven 2.2.1 (r801777; 2009-08-06 12:16:01-0700) Java version: 1.6.0_17 Java home: C:\Sun\SDK\jdk\jre Default locale: en_US, platform encoding: Cp1252 OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows" Ha configurado de manera exitosa Maven para utilizarlo con los ejemplos en este manual. Captulo 1. Prerequisitos para el uso de este manual 11 1.2. Configuracin especial de Maven para los ejemplos del microcontenedor Maven es un sistema modular de construccin que llama las dependencias cuando se necesitan. Los ejemplos en este manual asumen que ha includo el bloque de XML en Ejemplo 1.1, Archivo settings.xml de ejemplo en su ~/.m2/settings.xml (Linux) o C:\Documents and Settings\username\.m2\settings.xml (Windows). Si el archivo no existe entonces crelo primero. Ejemplo 1.1. Archivo settings.xml de ejemplo <settings> <profiles> <profile> <id>jboss.repository</id> <activation> <property> <name>!jboss.repository.off</name> </property> </activation> <repositories> <repository> <id>snapshots.jboss.org</id> <url>http://snapshots.jboss.org/maven2</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>repository.jboss.org</id> <url>http://repository.jboss.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>repository.jboss.org</id> <url>http://repository.jboss.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>snapshots.jboss.org</id> <url>http://snapshots.jboss.org/maven2</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> </settings> JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 12 1.3. Descarga de los ejemplos Los ejemplos en este manual le muestran cmo crear un proyecto maven que dependa del JBoss Microcontainer utilizando Maven. Puede descargarlos de images/examples.zip . Esta ubicacin cambiar pero la hemos includo para su conveniencia. Despus de descargar el archivo ZIP que contiene los ejemplos, extraiga su contenido en un lugar conveniente y mire los ejemplos para familiarizarse con su estructura. Captulo 1. Prerequisitos para el uso de este manual 13 Captulo 2. Introduccin al microcontenedor El microcontenedor JBoss es un rediseo del JBoss JMX Microkernel para soportar la implementacin POJO directa y el uso autnomo fuera del servidor de aplicaciones JBoss. El microcontenedor est diseado para llenar las necesidades especificas de los desarrolladores Java que queran utilizar tcnicas de programacin orientadas a objetos para implementar software de manera rpida. Adems permite implementar software en un amplio rango de dispositivos desde plataformas de computacin mviles, entornos de computacin de grande escala y lo que se encuentre entre estos dos. 2.1. Funcionalidades Todas las funcionalidades del microkernel JMX Implementacin POJO directa (no hay necesidad de estndar/XMBean o MBeanProxy) Inyeccin directa de dependencias de estilo IOC Administracin mejoarada del ciclo de vida Control adicional sobre las dependencias Integracin transparente AOP Sistema virtual de archivos Marco de trabajo de implementacin virtual Carga de clase OSGi 2.2. Definiciones Este manual usa algunos trminos que puede que no le sean familiares. Algunos de ellos se definen en Lista de definicin del mMicrocontenedor. Lista de definicin del mMicrocontenedor Microkernel JMX JBoss JMX Microkernel es un entorno Java modular. Es diferente de los entornos estndar como J2EE ya que el desarrollador puede escoger exactamente los componentes que son parte del entorno y dejar por fuera el resto. POJO Un POJO (del ingls Plain Old Java Object) es un objeto Java modular y reutilizable. El nombre se utiliza para enfatizar que un objeto dado es un objeto Java normal, no es un objeto especial y en particular no es un JavaBean empresarial. El trmino lo utiliz por primera vez Martin Fowler, Rebecca Parsons y Josh MacKenzie in September 2000 en una charla en la cual estaban resaltando los muchos beneficios de codificar la lgica empresarial en objetos java normales en lugar de utilizar beans de entidad. Bean Java Un bean Java es un componente software re-utilizable que se puede manipular visualmente en una herramienta de construccin. Un bean Java es un pedazo de cdigo independiente. No requiere herencias de ninguna clase o interfaz base en particular. Aunque los beans Java se crean principalmente en IDEs grficos tambin se pueden desarrollar en simples editores de texto. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 14 AOP Aspect-Oriented Programming (AOP) es un paradigma de programacin en el cual las funciones secundarias o de soporte se aislan de la lgica empresarial del programa principal. Es un sub-grupo de la programacin orientada a objetos. 2.3. Instalacin El microcontenedor es una parte integral de la plataforma empresarial. En el manual de configuracin y administracin encontrar mayor informacin sobre la instalacin y configuracin de la plataforma empresarial. Captulo 2. Introduccin al microcontenedor 15 Captulo 3. Construccin de servicios Los servicios son pedazos de cdigo que realizan tareas que mltiples clientes necesitan. Poara nuestro propsito pondremos algunas restricciones adicionales en la definicin de un servicio. Los servicios deben tener nombres nicos, a los cuales se puede hacer referencia o los clinetes pueden llamar. El interior de un servicio debe ser invisible y sin importancia para los clientes. Este es el concepto "caja negra"de la programacin orientada a objetos (OOP del ingls object-oriented programming). En OOP, cada objeto es independente y ningn otro objeto necesita saber cmo hace su trabajo. En el contexto del microcontenedor, los servicios se construyen desde POJOs. Un POJO es casi un servicio como tal pero no se puede acceder por un nombre nico y debe ser creado por el cliente que lo necesita. Aunque un POJO se debe crear en tiempo de ejecucin por parte del cliente, no es necesario implementarlo por medio de una clase separada con el fin de proporcionar una interfaz bien definida. Con tal de que no se borren los mtodos y campos y el acceso a ellos no sea restringido, no hay necesidad de recompilar los clientes para utilizar un POJO recin creado. Nota El iImplementar una interfaz solo es necesario con el fin de permitir que un cliente escoja entre implementaciones opcionales. Si el cliente se compila frente a una interfaz, se pueden proporcionar muchas implementaciones diferentes de la interfaz sin tener que recompilar el cliente. La interfaz se asegura de que las firmas de mtodo no cambien. El resto de este manual consiste de la creacin del servicio de recursos humanos utilizando el microcontenedor para capturar y modularizar la lgica empresarial de la aplicacin. Despus de que el microcontenedor est instalado, el cdigo de ejemplo se encuentra en examples/User_Guide/gettingStarted/humanResourcesService. 3.1. Introduccin al ejemplo de recusos humanos Al familiarizarse con la estructura del directorio de los archivos en el ejemplo note que usa la estructura del directorio estndar Maven. Los archivos fuente Java se encuentran en los paquetes debajo del directorio examples/User_Guide/gettingStarted/humanResourcesService/src/main/java/org/j boss/example/service despus de extraer el archivo ZIP. Cada una de estas clases representa un POJO simple que no implementa ninguna interfaz especial. La clase ms importante es HRManager, la cual representa el punto de entrada del servicio proporcionando todos los mtodos pblicos que los clientes llamarn. Mtodos que la clase HRManager proporciona addEmployee(Employee employee) removeEmployee(Employee employee) getEmployee(String firstName, String lastName) getEmployees() getSalary(Employee employee) setSalary(Employee employee, Integer newSalary) JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 16 isHiringFreeze() setHiringFreeze(boolean hiringFreeze) getSalaryStrategy() setSalaryStrategy(SalaryStrategy strategy) El servicio de recursos humanos est compuesto de unas pocas clases, las cuales mantienen una lista de empleados y sus detalles (direcciones y salarios, en este caso). Al utilizar la interfaz SalaryStrategy es posible configurar el HRManager de manera que hayan disponibles diferentes implementaciones de la estrategia de salario para poner lmites mnimos y mximos en los salarios para diferentes roles de empleados. 3.2. Compilacin del proyecto de ejemplo HRManager Para compilar el cdigo fuente, escriba mvn compile desde el directorio humanResourcesService/. Esto crea un nuevo directorio llamado target/classes, el cual contiene las clases compiladas. Para limpiar el proyecto y borrar el directorio destino emita el comando mvn clean. 3.3. Creacin de POJOs antes de poder utilizar un POJO, necesita crearlo. Necesita un mecanismo de nombrado que le permita registrar una referencia a la instancia POJO con un nombre. Los clientes necesitan este nombre para utilizar el POJO. El microcontenedor proporciona dicho mecanismo: un controlador. Un controlador le permite implementar sus servicios basados en POJO en un entorno en tiempo de ejecucin. 3.3.1. Descriptores de implementacin XML Despus de compilar las clases, use un descriptor de implementacin XML para crear instancias de ellas. El descriptor contiene una lista de beans representandos instancias individuales. Cada bean tiene un nombre nico de manera que los clientes lo pueden llamar en tiempo de ejecucin. El siguiente descriptor implementa una instancia del HRManager: <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="HRService" class="org.jboss.example.service.HRManager"/> </deployment> Este XML crea una instancia de la clase HRManager y la registra con el nombre HRService. Este archivo se le pasa a un programa de implementacin XML asociado con el microcontenedor en tiempo de ejecucin, el cual realiza la implementacin real e instancia los beans. 3.4. Conexin de POJOs Las instancias individuales POJO solo pueden proporcionar comportamientos relativamente simples. El verdadero poder de los POJOs viene de conectarlos entre ellos para realizar tareas complejas. Cmo puede conectar POJOs para seleccionar diferentes implementaciones de estrategia de salarios? El siguiente descriptor de implementacin XML hace justamente eso: Captulo 3. Construccin de servicios 17 <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="HRService" class="org.jboss.example.service.HRManager"> <property name="salaryStrategy"><inject bean="AgeBasedSalary"/></property> </bean> <bean name="AgeBasedSalary" class="org.jboss.example.service.util.AgeBasedSalaryStrategy"/> </deployment> Este XML crea una instancia de la implementacin de la estrategia de salario incluyendo un elemento <bean> adicional. Esta vez, se selecciona AgeBasedSalaryStrategy. Luego el cdigo inyecta una referencia a este bean en la instancia de HRManager creada utilizando el bean HRService. La inyeccin es posible ya que la clase HRManager contiene un mtodo setSalaryStrategy(SalaryStrategy strategy). Mientras tanto detrs de bastidores el microcontenedor JBoss llama a este mtodo en la instancia HRManager recin creada y le pasa una referencia a la instancia AgeBasedSalaryStrategy. El descriptor de implementacin XML causa la misma secuencia de eventos como si hubiera escrito el siguiente cdigo: HRManager hrService = new HRManager(); AgeBasedSalaryStrategy ageBasedSalary = new AgeBasedSalaryStrategy(); hrService.setSalaryStrategy(ageBasedSalary); Adems de realizar la inyeccin por medio de los mtodos setter de las propiedades, el microcontenedor JBoss tambin puede realizar la inyeccin por medio de parmetros del constructor si es necesario. Para obtener mayores detalles consulte el captulo sobre 'Inyeccin' en la parte II 'Desarrollo POJO.' 3.4.1. Consideraciones especiales Aunque es posible el crear instancias de clases utilizando el elemento <bean> en el descriptor de implementacin, no siempre es la mejor manera. Por ejemplo, el crear instancias de las clases Employee y Address es innecesario ya que el cliente crea estas en respuesta a la entrada del usuario. Todava son parte del servicio pero no se referencian en el descriptor de implementacin. Realice comentarios en su cdigo Puede definir mltiples beans dentro de un descriptor de implementacin en tanto cada uno tenga un nombre nico, el cual se utiliza para realizar inyecciones como se mostr anteriormente. Sin embargo, todos los beans no necesariamente representan servicios. Aunque un servicio se puede implementar utilizando un solo bean, usualmente se utilizan mltiples beans. Un bean usualmente representa el punto de entrada del servicio y contiene los mtodos pblicos que los clientes llaman. En este ejemplo, el punto de entrada es el bean HRService. El descriptor de implementacin XML no indica si un bean representa un servicio o si un bean es el punto de entrada del servicio. Es una buena idea el utilizar comentariosy un esquema de nombrado obvio para diferenciar los beans de servicio de los beans que no son de servicio. 3.5. Trabajar con servicios Despus de crear POJOs y conectarlos para formar servicios, necesita configurar los servicios, JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 18 probarlos y empacarlos. 3.5.1. Configuracin de un servicio Los servicios se pueden configurar de dos maneras: Inyeccin de referencias entre instancias POJO Inyeccin de valores en propiedades POJO En este ejemplo se utiliza el segundo mtodo. El siguiente descriptor de implementacin configura la instancia de HRManager de la siguiente manera: Se implementa una congelacin en la contratacin La AgeBasedSalaryStrategy implementa un nuevo valor de salario mnimo y mximo. El inyectar referencias enter instancias POJO es una manera de configurar un servicio; sin embargo, tambin podemos inyectar valores en propiedades POJO. El siguiente descriptor de implementacin muestra cmo podemos configurar la instancia HRManager para que realice una congelacin en la contratacin y para que la AgeBasedSalaryStrategy tenga un valor de salario mnimo y mximo: <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="HRService" class="org.jboss.example.service.HRManager"> <property name="hiringFreeze">false</property> <property name="salaryStrategy"><inject bean="AgeBasedSalary"/></property> </bean> <bean name="AgeBasedSalary" class="org.jboss.example.service.util.AgeBasedSalaryStrategy"> <property name="minSalary">1000</property> <property name="maxSalary">80000</property> </bean> </deployment> Las clases deben tener mtodos setter pblicos para las propiedades relevantes de manera que los valores se puedan inyectar. Por ejemplo, la clase HRManager tiene un mtodo setHiringFreeze(boolean hiringFreeze) y la clase AgeBasedSalaryStrategy tiene los mtodos setMinSalary(int minSalary) y setMaxSalary(int maxSalary). Los valores en el descriptor de implementacin se convierten de cadenas a los tipos relevantes (boolean, int, etc) por medio de PropertyEditors JavaBean. Muchos PropertyEditors se brindan por defecto para los tipos estndar, pero puede crear los propios si es necesario. Consulte el captulo de propiedades en la parte II 'Desarrollo POJO' para obtener mayores detalles. 3.5.2. Probar un servicio Despus de crear sus POJOs y de conectarlos para formar servicios, necesita probarlos. JBoss Microcontainer le permite la prueba de unidades de POJOs individuales as como de servicios por medio del uso de una clase MicrocontainerTest. La clase org.jboss.test.kernel.junit.MicrocontainerTest hereda de junit.framework.TestCase, configurando cada prueba realizando bootstrap en JBoss Captulo 3. Construccin de servicios 19 Microcontainer y agregando un BasicXMLDeployer. Luego busca la ruta de clase para un descriptor de implementacin XML con el mismo nombre que la clase de prueba terminado en .xml y que se encuentra en el nombre del paquete de la clase que representa la estructura del directorio. Cualquier bean que se encuentre en este archivo se implementan y luego se pueden acceder utilizando un mtodo conveniente llamado getBean(String name). Puede encontrar ejemplos de estos descriptores de implementacin en Ejemplo 3.1, Listado del directorio src/test/resources. Ejemplo 3.1. Listado del directorio src/test/resources log4j.properties org jboss example service HRManagerAgeBasedTestCase.xml HRManagerLocationBasedTestCase.xml HRManagerTestCase.xml util AgeBasedSalaryTestCase.xml LocationBasedSalaryTestCase.xml El cdigo de prueba se encuentra en el directorio the src/test/java : Ejemplo 3.2. Listado del directorio src/test/java org jboss example service HRManagerAgeBasedTestCase.java HRManagerLocationBasedTestCase.java HRManagerTestCase.java HRManagerTest.java HRManagerTestSuite.java util AgeBasedSalaryTestCase.java LocationBasedSalaryTestCase.java SalaryStrategyTestSuite.java La clase HRManagerTest extiende MicrocontainerTest con el fin de configurar un nmero de empleados a utilizar como base para la prueba. Ejemplos individuales luego crean sub-clases en HRManagerTest para realizar el trabajo en s. Tambin se includyen un par de clases TestSuite que se utilizan para agrupar ejemplos individuales por comodidad. Para ejecutar las pruebas escriba mvn test desde el directorio humanResourcesService/. Debe ver alguna salida de registro DEBUG, el cual muestra a JBoss Microcontainer inicando e implementando los desde el archivo XML relevante antes de ejecutar cada prueba. Al final de la prueba se borra la implementacin de los beans y se apaga el microcontenedor. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 20 Nota Algunas de las pruebas tal como HRManagerTestCase, AgeBasedSalaryTestCase y LocationBasedSalaryTestCase prueban POJOs individuales. Otras pruebas tal como HRManagerAgeBasedTestCase y HRManagerLocationBasedTestCase prueban servicios enteros. De cualquier manera, las pruebas se ejecutan de la misma manera. El utilizar la clase MicrocontainerTest facilita el configurar y conducir pruebas completas de cualquier parte de su cdigo. Las clases Address y Employee no se anidan aqu. El escribir pruebas para ellas queda de su parte. 3.5.3. Empacar un servicio Despus de probar su servicio es hora de empacarlo de manera que otros puedan utilizarlo. La manera ms simple de hacer esto es crear una JAR que contenga todas las clases. Puede escoger el incluir el descriptor de implementacin si hay una manera predeterminada sensible de configurar el servicio, pero es opcional. Procedimiento 3.1. Empacar un servicio 1. Ponga el descriptor de implementacin en el directorio META-INF (opcional) Si decide incluir el descriptor de implementacin por convencin se debe llamar jboss- beans.xml y se debe poner en un directorio META-INF. Esta es la distribucin predeterminada para la plataforma empresarial as que el programa de implementacin JAR reconoce esta distribucin y realiza la implementacin de manera automtica. El descriptor de implementacin no se incluye en el ejemplo de recursos humanos ya que el servicio se configura modificando el descriptor directamente como un archivo a separado. 2. Generacin de la JAR Para generar una JAR que contenga todas las clases compiladas introduzca mvn package desde el directorio humanResourcesService/. 3. Hacer la JAR disponible para otros proyectos Maven Para hacer la JAR disponible para los otros proyectos Maven introduzca mvn install con el fin de copiarlo a su repositorio Maven local. La distribucin final de la JAR se puede ver en Ejemplo 3.3, Listado de los directorios org/jboss/example/service y META-INF. Captulo 3. Construccin de servicios 21 Ejemplo 3.3. Listado de los directorios org/jboss/example/service y META-INF `-- org `-- jboss `-- example `-- service |-- Address.java |-- Employee.java |-- HRManager.java `-- util |-- AgeBasedSalaryStrategy.java |-- LocationBasedSalaryStrategy.java `-- SalaryStrategy.java `--META-INF `-- MANIFEST.MF `-- maven `-- org.jboss.micrcontainer.examples `-- humanResourceService Nota Maven crea automticamente el directorio META-INF/maven y no estar presente si est utilizando uns sistema de construccin diferente. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 22 Captulo 4. Uso de los servicios El captulo anterior le mostr cmo crear, configurar, probar y empacar un servicio. El siguiente paso es crear un cliente, el cual realizar el trabajo utilizando el servicio. El cliente en este ejemplo usa un Text User Interface (TUI) para aceptar entradas del usuario y presentar los resultados. Esto reduce el tamao y complejidad del cdigo ejemplo. Todos los archivos necesarios se encuentran en el directorio examples/User_Guide/gettingstarted/commandLineClient, el cual sigue la estructura del directorio estndar Maven, como se puede ver en Ejemplo 4.1, Listar el directorio examples/User_Guide/gettingstarted/commandLineClient. Ejemplo 4.1. Listar el directorio examples/User_Guide/gettingstarted/commandLineClient pom.xml src main assembly aop.xml classloader.xml common.xml pojo.xml config aop-beans.xml classloader-beans.xml pojo-beans.xml run.sh java org jboss example client Client.java ConsoleInput.java EmbeddedBootstrap.java UserInterface.java resources log4j.properties test java org jboss example client ClientTestCase.java ClientTestSuite.java MockUserInterface.java resources jboss-beans.xml target classes log4j.properties El cliente consiste de las tres clases y una interfaz que se encuentra en el directorio Captulo 4. Uso de los servicios 23 org/jboss/example/client. UserInterface describe los mtodos que el cliente llama en tiempo de ejecucin para solicitar lla entrada del usuario. ConsoleInput es una implementacin de UserInterface que crea un TUI que el usuario utiliza para interactuar con el cliente. La ventaja de este diseo es que puede crear fcilmente una implementacin Swing de UserInterface en una fecha posterior y puede reemplazar el TUI con un GUI. Tambin puede simular el proceso de ingreso de datos con un script. Luego puede chequear el comportamiento del cliente automticamente usando ejemplos JUnit convencionales que se encuentran en Ejemplo 3.2, Listado del directorio src/test/java. Para que la construccin funcione primero debe construir e instalar auditAspect.jar desde el directorio examples/User_Guide/gettingStarted/auditAspect usando el mvn install command. Se crean un nmero de distribuciones diferentes de clientes, incluyendo una basada en AOP, la cual depende de que auditAspect.jar se encuentre disponible en el repositorio local Maven. Si anteriormente escribi mvn install desde el directorio examples/User_Guide/gettingStarted entonces humanResourcesService.jar y auditAspect.jar ya se han construdo y empacado junto con el cliente as que este paso no ser necesario. Para compilar el cdigo fuente, se realizan todos los pasos que se encuentran en Procedimiento 4.1, Compilacin del cdigo fuente al emitir el comando mvn package desde el directorio commandLineClient. Procedimiento 4.1. Compilacin del cdigo fuente 1. Ejecute las pruebas de las unidades. 2. construya una JAR cliente. 3. Ensamble una distribucin que contenga todos los archivos necesarios. Despus de compilar y empacar el cliente, la estructura del directorio en el diretcorio commandLineClient/target incluye los subdirectorios descritos en Ejemplo 4.2, Los subdirectorios del directorio commandLineClient/target. Ejemplo 4.2. Los subdirectorios del directorio commandLineClient/target client-pojo utilizado para llamar al servicio sin AOP. client-cl utilizado para demostrar las funcionalidades de carga de clase. client-aop Agregar soporte AOP. Consulte Captulo 5, Agregar comportamiento con AOP para obtener mayores detalles. Cada sub-directorio representa una distribucin diferente con todos los scripts shell, JARs y descriptores de implementacin XML que se necesitan para ejecutar el cliente en diferentes configuraciones. El resto de este captulo usea la distribucin client-pojo que se encuentra en el JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 24 sub-directorio client-pojo, el cual se lista en Ejemplo 4.3, Listado del directorio client-pojo. Ejemplo 4.3. Listado del directorio client-pojo |-- client-1.0.0.jar |-- jboss-beans.xml |-- lib | |-- concurrent-1.3.4.jar | |-- humanResourcesService-1.0.0.jar | |-- jboss-common-core-2.0.4.GA.jar | |-- jboss-common-core-2.2.1.GA.jar | |-- jboss-common-logging-log4j-2.0.4.GA.jar | |-- jboss-common-logging-spi-2.0.4.GA.jar | |-- jboss-container-2.0.0.Beta6.jar | |-- jboss-dependency-2.0.0.Beta6.jar | |-- jboss-kernel-2.0.0.Beta6.jar | |-- jbossxb-2.0.0.CR4.jar | |-- log4j-1.2.14.jar | `-- xercesImpl-2.7.1.jar `-- run.sh Para ejecutar el cliente, cmbiese al directorio client-pojo y escriba ./run.sh. Aparecer el The Ejemplo 4.4, Pantalla del men de HRManager. Ejemplo 4.4. Pantalla del men de HRManager Men: d) Implementar el servicio de recursos humanos u) Borrar la implementacin del servicio de recursos humanos a) Agregar empleado l) Listar los empleados r) Borrar empleado g) Ver un salario s) Establecer un salario t) Alternar la congelacin de la contratacin m) Ver el men p) Imprimir el estatus del servicio q) Salir > Para seleccionar una opcin, introduzca la letra que se muestra en el lado izquierdo y oprima RETURN. Por ejemplo para ver lsa opciones del men introduzca m y luego presione RETURN. El introducir ms de una letra o el introducir una opcin invlida genera un mensaje de error. Captulo 4. Uso de los servicios 25 Importante El script run.sh establece el entorno de ejecucin agregando todas las JARs que se encuentran en el directorio lib/ a la ruta de clase usando la propiedad del sistema java.ext.dirs. Tambin agrega el directorio actual y la client-1.0.0.jar usando la eiqueta -cp de manera que el descriptor de implementacin jboss-beans.xml se encuentre en tiempo de ejecucin junto con la clase org.jboss.example.client.Client, la cual se llama para iniciar la aplicacin. 4.1. Bootstrap del microcontenedor Antes de utilizar el cliente para implementar y llamar a su servicio, mire detalladamente lo que pas durante la construccin: public Client(final boolean useBus) throws Exception { this.useBus = useBus; ClassLoader cl = Thread.currentThread().getContextClassLoader(); url = cl.getResource("jboss-beans.xml"); // Start JBoss Microcontainer bootstrap = new EmbeddedBootstrap(); bootstrap.run(); kernel = bootstrap.getKernel(); controller = kernel.getController(); bus = kernel.getBus(); }
Primero que todo se cre una URL que representa el descriptor de implementacin jboss-beans.xml. Esto se necesita luego de manera que el programa de implementacin XML pueda implementar y borrar la implementacin de los beans declarados en el archivo. El mtodo getResource() del cargador de clase de la aplicacin se utiliza ya que se incluye el archivo jboss-beans.xml en la ruta de clase. esto es opcional; el nombre y ubicacin del descriptor de implementacin no son importantes en tanto la URL sea vlida y se pueda llegar a ella. Luego se crea una instancia de JBoss Microcontainer junto con un programa de implementacin XML. Este proceso se llama bootstrapping y se proporciona una clase llamada BasicBootstrap como parte del microcontenedor para tener en cuenta la configuracin programtica. Para agregar un programa de implementacin XML, extienda BasicBootstrap para crear una clase EmbeddedBootstrap y sobrescriba el mtodo protegido bootstrap() as: JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 26 public class EmbeddedBootstrap extends BasicBootstrap { protected BasicXMLDeployer deployer; public EmbeddedBootstrap() throws Exception { super(); } public void bootstrap() throws Throwable { super.bootstrap(); deployer = new BasicXMLDeployer(getKernel()); Runtime.getRuntime().addShutdownHook(new Shutdown()); } public void deploy(URL url) { ... deployer.deploy(url); ... } public void undeploy(URL url) { ... deployer.undeploy(url); ... } protected class Shutdown extends Thread { public void run() { log.info("Shutting down"); deployer.shutdown(); } } }
El gancho shutdown se asegura de que cuando la MVJ termina, se borra la implementacin de todos los beans en el orden correcto. Los mtodos pblicos deploy/undeploy delegan al BasicXMLDeployer de manera que los beans declarados en jboss-beans.xml se puedan implementar y borrar. Finalmente las referencias al controlador del microcontenedor y el bus se reestablecen as que puede buscar las referencias de beans por su nombre y puede accederlas directamente o indirectamente cuando los necesite. 4.2. Implementacin del servicio Despus de crear el cliente puede implementar el servicio de recursos humanos. Esto se logra introduciendo la opcin d del TUI. La salida indica que el BasicXMLDeployer ha analizado sintcticamente el archivo jboss-beans.xml usando la URL y ha instanciado los beans que se encuentran adentro. Captulo 4. Uso de los servicios 27 Nota El microcontenedor puede instanciar los beans ya que sus clases estn disponibles en la ruta de clase de extensin dentro del archivo lib/humanResourcesService.jar. Tambin puede poner estas clases en una estructura de directorio expandido y agregarla a la ruta de clase de la aplicacin, pero el empacarlos en una JAR usualmente es ms conveniente. El descriptor de implementacin es completamente separado del archivo humanResourcesService.jar. Esto permite modificarlo para propsitos de pruebas. El archivo jboss-beans.xml en el ejemplo contiene algunos fragmentos de XML comentados, lo cual muestra algunas de las configuraciones posibles. <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="HRService" class="org.jboss.example.service.HRManager"> <!-- <property name="hiringFreeze">true</property> <property name="salaryStrategy"><inject bean="AgeBasedSalary"/></property> --> </bean> <!-- <bean name="AgeBasedSalary" class="org.jboss.example.service.util.AgeBasedSalaryStrategy"> <property name="minSalary">1000</property> <property name="maxSalary">80000</property> </bean> <bean name="LocationBasedSalary" class="org.jboss.example.service.util.LocationBasedSalaryStrategy"> <property name="minSalary">2000</property> <property name="maxSalary">90000</property> </bean> --> </deployment>
Importante Dependiendo de la manera en que acceda el servicio en tiempo de ejecucin es posible que necesite apagar la aplicacin y re-iniciarla para volver a implementar el servicio y ver sus cambios. Esto reduce la flexibilidad de la aplicacin, pero incrementa el rendimiento en tiempo de ejecucin. Opcionalmente puede simplemente volver a implementar el servicio mientras que la aplicacin est ejecutando. Esto incrementa la flexibilidad pero disminuye el rendimiento en tiempo de ejecucin. Mantenga estas opciones en consideracin al disear sus aplicaciones. 4.3. Acceso directo Si no se le pasan parmetros al script run.sh cuando se inicia el cliente entonces se busca una JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 28 referencia al bean HRService usando el controlador del microcontenedor despus de que se ha implementado el servicio: private HRManager manager; ... private final static String HRSERVICE = "HRService"; ... void deploy() { bootstrap.deploy(url); if (!useBus && manager == null) { ControllerContext context = controller.getInstalledContext(HRSERVICE); if (context != null) { manager = (HRManager) context.getTarget(); } } }
En lugar del buscar inmediatamente una referencia a la instancia del bean, el ejemplo primero busca una referencia a un ControllerContext, luego obtiene una referencia a la instancia del bean del contexto utilizando el mtodo getTarget(). El bean puede existir dentro del microcontenedor en cualquiera de los estados listados en Estados de un Bean dentro del microcontenedor. Estados de un Bean dentro del microcontenedor NO_INSTALADO DESCRITO INSTANCIADO CONFIGURADO INSTALADO Para mantener el registro de en qu estado se encuentra el bean, envulvalo en otro objeto llamado un context, el cual describe el estado actual. El nombre del contexto es el mismo que el nombre del bean. Una vez que un contexto alcanza el estado INSTALADO entonces el bean que representa se considera implementado. Despus de crear una referencia a la instancia del bean que representa el punto de entrada del servicio, puede llamar a los mtodos en este para realizar tareas: @SuppressWarnings("unchecked")
Set<Employee> listEmployees() { if (useBus) ... else return manager.getEmployees(); }
El cliente est accediendo el servicio directamente ya que est utilizando una referencia a la instancia Captulo 4. Uso de los servicios 29 del bean real. El rendimiento es bueno ya que cada llamada de mtodo va directamente al bean. Sin embargo, Qu pasa si desea re-configurar el servicio y volver a implementarlo mientras la aplicacin est ejecutando? La re-configuracin se logra realizando cambios al descriptor de implementacin XML y guardando el archivo. Con el fin de volver a implementar el servicio, se debe borrar la implementacin de la instancia actual. Al borrar la implementacin el controlador del microcontenedor libera su referencia a la instancia del bean, junto con los beans dependientes. Posteriormente estos beans se harn disponibles para el servicio de recoleccin de basura ya que la aplicacin ya no los necesita ms. El volver a implementar el servicio crea nuevas instancias del bean representando la nueva configuracin. Cualquier bsqueda posterior de parte de los clientes recuperar las referencias a estas nuevas instancias y podrn volver a acceder el servicio re-configurado. El problema es que la referencia a la instancia del bean que representa nuestro punto de entrada del servicio va al cach cuando implementa el servicio por primera vez. El borrar la implementacin del servicio no tienen ningn efecto ya que la instancia del bean todava se puede acceder usando la referencia en cach y no ir a la basura hasta que el cliente la libere. De la misma manera, el implementar el servicio de nuevo no generar otra bsqueda ya que el cliente ya tiene una referencia en cach. Por lo tanto continuar utilizando la instancia del bean representando la configuracin del servicio inicial. Puebe probar este comportamiento escribiendo u seguido de RETURN para borrar la implementacin del servicio actual. Debe poder acceder el servicio todava desde el cliente aunque haya 'borrado' la implementacin. Luego, realice algunos cambios a la configuracin utilizando el archivo jboss- beans.xml, guarde el archivo y vuelva a implementarlo usando la opcin d. Puede imprimir el estatus del servicio utilizando la opcin p, la cual muestra que el cliente todava est accediendo la instancia inicial del servicio que se implement. Aviso Incluso si modifica el cliente para que busque una nueva referencia cada vez que el servicio se vuelve a implementar, es posible que los nuevos desarrolladores entreguen por error copias de esta referencia a otros objetos. Si todas estas referencias no se limpian al volver a realizar la implementacin se puede presentar el mismo problema de cach. Para volver a implementar el servicio reconfigurado de manera confiable, apague la aplicacin completamente utilizando la opcin 'q' y reincela usando el script run.sh. Para servicios empresariales tal como transacciones, mensajera y persistencia este es un comportamiento completamente aceptable ya que generalmente se utilizan. No se pueden volver a implementar en tiempo de ejecucin y tambin se benefician del alto rendimiento dado por el uso del acceso directo. Si su servicio cae en esta categoria, considere el utilizar el acceso directo por medio del controlador del microcontenedor. 4.4. Acceso indirecto El script run.sh se puede llamar con un parmetro opcional bus, el cual hace que las llamadas al servicio de recursos humanos utilicen el bus del microcontenedor. En lugar de utilizar una referencia directa a la instancia del bean que se obtuvo del controlador microcontenedor, el nuevo comportamiento es llamar a un mtodo invoke() en el bus, pasando el nombre del bean, el nombre del mtodo, los argumentos del mtodo y los tipos de mtodo. El bus usa esta informacin para llamar al bean de parte del cliente. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 30 private final static String HRSERVICE = "HRService"; ... @SuppressWarnings("unchecked") Set<Employee> listEmployees() { if (useBus) return (Set<Employee>) invoke(HRSERVICE, "getEmployees", new Object[] {}, new String[] {}); else return manager.getEmployees(); } private Object invoke(String serviceName, String methodName, Object[] args, String[] types) { Object result = null; try { result = bus.invoke(serviceName, methodName, args, types); } catch (Throwable t) { t.printStackTrace(); } return result; } El bus busca la referencia a la instancia del bean nombrado y llama al mtodo seleccionado usando la reflexin. El cliente nunca tiene una referencia directa a la instancia del bean as que se dice que accede al servicio indirectamente. Ya que el bus no pone en el cach la referencia puede realizar de manera segura los cambios a la configuracin del servicio y se puede volver a implementar en tiempo de ejecucin. Las llamadas posteriores por parte del cliente utilizarn la nueva referencia tal como se espera. El cliente y el servicio han sido desvinculados. Nota Este comportamiento se puede probar implementado el servicio y utilizando la opcin p para imprimir el estatus. Borre la implementacin del servicio utilizando la opcin u y observe que es inaccesible. Luego realice algunos cambios al archivo jboss-beans.xml, guarde los cambios e implemente de nuevo usando la opcin d. Imprima el estatus de nuevo usando la opcin p. El cliente est accediendo la nueva configuracin del servicio. Ya que el bus usa la reflecin para llamar instancias del bean, es un poco ms lento que el acceso directo. El beneficio del enfoque es que solo el bus tiene referencias a las instancias del bean. Cuando un servicio se vuelve a implementar, todas las referencias existentes se pueden limpiar y reemplazar con las nuevas. De esta manera, se puede volver a implementar de manera segura un servicio en tiempo de ejecucin. Los servicios que no se utilizan con tanta frecuencia o que son especificos para ciertas aplicaciones son buenos candidatos para acceso indirect usando el bus del microcontenedor. Con frecuencia la reduccin en el rendimiento es superior a la flexibilidad que proporciona. 4.5. Carga de clase dinmica Hasta ahora ha utilizado los cargadores de clase de aplicacin y extensin para cargar todas las clases en la aplicacin. La ruta de clase de la aplicacin se configura por medio del script run.sh utilizando la etiqueta -cp para incluir el directorio actual y la client-1.0.0.jar como se puede ver aqu: Captulo 4. Uso de los servicios 31 java -Djava.ext.dirs=`pwd`/lib -cp .:client-1.0.0.jar org.jboss.example.client.Client $1 Por comodidad las JARs en el directorio lib se agregaron a la extensin de la ruta de clase del cargador de clase usando la propiedad del sistema java.ext.dirs, en lugar de listar la ruta completa para cada una de las JARs despus de la etiqueta -cp. Ya que la extensin classloader es padre de la aplicacin classloader, las clases del cliente pueden encontrar todas las clases del microcontenedor y las clases del servicio de recursos humanos en tiempo de ejecucin. Nota Con las versiones de Java 6 y posteriores puede utilizar un comodn para incluir todas las JARs en un directorio con la etiqueta -cp: java -cp `pwd`/lib/*:.:client-1.0.0.jar org.jboss.example.client.Client $1 Aqu todas las clases en la aplicaci se agregarn a la ruta de clase del cargador de clase de la aplicacin y extensin de la ruta de clase del cargador de clase retendr su valor predeterminado. Qu pasa si necesita implementar un servicio adicional en tiempo de ejecucin? Si el nuevo servicio est empacado en un archivo JAR debe ser visible para un cargador de clase antes de que cualquiera de sus clases puedan ser cargadas. Ya que ya configur la ruta de clase para el cargador de clase de la aplicacin (y el cargador de clase de extensin) en el arranque, no es fcil el agregar la URL de la JAR. La misma situacin aplica si las clases del servicio se encuentran en una estructura de directorio. A menos de que el directorio a nivel superior se encuentre en el directorio actual (el cual est en la ruta de clase de la aplicacin) entonces el cargador de clase de la aplicacin no encoentrar las clases. Si desea volver a implementar un servicio existente cambiando algunas de sus clases, necesita trabajar teniendo en cuenta las restricciones de seguridad, las cuales le impiden a un cargador de clase existente el volver a cargar las clases. La meta es crear un nuevo cargador de clases que conozca la ubicacin de las clases del nuevo servicio o que pueda cargar nuevas versiones de las clases de un servicio ya existente con el fin de implementar los beans del servicio. JBoss Microcontainer usa el elemento <classloader> en el descriptor de implementacin para lograr esto. La distribucin client-cl contiene el archivo listado en el Ejemplo 4.5, Listado del directorio commandLineClient/target/client-cl . JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 32 Ejemplo 4.5. Listado del directorio commandLineClient/target/client-cl |-- client-1.0.0.jar |-- jboss-beans.xml |-- lib | |-- concurrent-1.3.4.jar | |-- jboss-common-core-2.0.4.GA.jar | |-- jboss-common-core-2.2.1.GA.jar | |-- jboss-common-logging-log4j-2.0.4.GA.jar | |-- jboss-common-logging-spi-2.0.4.GA.jar | |-- jboss-container-2.0.0.Beta6.jar | |-- jboss-dependency-2.0.0.Beta6.jar | |-- jboss-kernel-2.0.0.Beta6.jar | |-- jbossxb-2.0.0.CR4.jar | |-- log4j-1.2.14.jar | `-- xercesImpl-2.7.1.jar |-- otherLib | `-- humanResourcesService-1.0.0.jar |`-- run.sh Se ha movido el archivo humanResourcesService.jar a un nuevo sub-directorio llamado otherLib. Ya no est disponible para los cargadores de clase de extensin o de la aplicacin, coya ruta de clase se configura en el script run.sh: java -Djava.ext.dirs=`pwd`/lib -cp .:client-1.0.0.jar org.jboss.example.client.Client $1 Para solucionar esto cree un nuevo cargador de clase durante la implementacin del servicio, crguela en las clases del servicio y cree instancias de los beans. Para ver cmo se logra esto vea el contenido del archivo jboss-beans.xml: Captulo 4. Uso de los servicios 33 <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="URL" class="java.net.URL"> <constructor>
1. Primero cree una instancia de java.net.URL llamada URL, usando la inyeccin de parmetros en el constructor para especificar la ubicacion del archivo humanResourcesService.jar en el sistema local de archivos. 2. Luego, cree una instancia de un URLClassLoader inyectando el bean URL en el constructor como nico elemento en el array. 3. Incluya un elemento <classloader> en su definicin de bean HRService e inyecte el bean customCL. Esto especifica que la clase HRManager necesita ser cargada por el cargador de clase customCL. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 34 Necesita una manera de decidir cul cargador de clase utilizar para los otros beans en la implementacin. Todos los beans en la implementacin utilizan el cargador de clase del contexto del hilo actual. En este caso el hilo que maneja la implementacin es el hilo principal de la aplicacin, el cual tiene su cargador de clase de contexto establecido para el cargador de clase de la aplicacin durnate el arranque. Si desea puede especificar un cargador de clase diferente para toda la implementacin utilizando un elemento <classloader> como se puede ver en Ejemplo 4.6, Especificar un cargador de clase diferente. Ejemplo 4.6. Especificar un cargador de clase diferente <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <classloader><inject bean="customCL"/></classloader> <bean name="URL" class="java.net.URL"> <constructor>
Esto sera necesario para permitir la reconfiguracin del service al borrar los comentarios de los beans AgeBasedSalary o LocationBasedSalary. Los cargadores de clase especificados a nivel del bean sobreescriben el cargador de clase a nivel de la implementacin. Para sobreescribir el cargador de clase a nivel de implementacin y utilizar el cargador de clase predeterminado para un bean, use el valor <null/> as: Captulo 4. Uso de los servicios 35 <bean name="HRService" class="org.jboss.example.service.HRManager"> <classloader><null/></classloader> </bean>
4.5.1. Problemas con cargadores de clase creados con los descriptores de implementacin Si crea un nuevo cargador de clase para su servicio utilizando el descriptor de implementacin es posible que no pueda acceder las clases cargadas por este desde el cargador de clase de la aplicacin. En el ejemplo HRManager, el cliente ya no puede poner en cach una referencia directa a la instancia del bean al utilizar el controlador del microcontenedor. Para ver este comportamiento inicie el cliente usando el comando run.sh y luego trate de implementar el servicio. Se presenta una excepcin java.lang.NoClassDefFoundError y la aplicacin termina. En este escenario debe usar el bus para acceder el servicio indirectamente y proporcionar acceso a cualquier clase compartida por el cliente en la ruta de clase de la aplicacin. En este ejemplo, las clases afectadas son Address, Employee y SalaryStrategy. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 36 Captulo 5. Agregar comportamiento con AOP La programacin orientada a objetos (OOP del ingls Object Oriented Programming) tiene muchas tcnicas tiles para el desarrollo de software incluyendo la encapsulacin, herencia y polimorfismo. Sin embargo, no soluciona el problema de la lgica de direccionamiento que con frecuencia se repite en muchas clases diferentes. Ejemplos de esto incluye los registros, seguridad y lgica transaccional, la cual es tradicionalmente codificada a fuego en cada clase. Este tipo de lgica se llama un asunto de corte transversal. La programacin orientada a aspectos (AOP del ingles Aspect Oriented Programming funciona para permitir el aplicar asuntos de corte transversal a las clases despus de que se han compilado. Esto mantiene el cdigo fuente libre de lgica, lo cual no es una parte central del propsito principal de la clase y optimiza el mantenimiento. El mtodo depende de la implementacin AOP. Usualmente si una clase implementa una interfaz, cada llamada de mtodo a una instancia de la clase primero pasa por un proxy. Este proxy implementa la misma interfaz, agregando el comportamiento requerido. Opcionalmente, si no se utiliza una interfaz entonces el cdigo byte java de la clase compilada se modifica: los mtodos originales se re-nombran y se reemplazan con mtodos que implementan la lgica de corte transversal. Luego estos nuevos mtodos llaman a los mtodos originales despus de haber ejecutado la lgica de corte transversal. Otro mtodo para lograr el mismo resultado es modificar el cdigo byte para crear una subclase de la clase original que sobreescribe sus mtodos. Los mtodos sobreescritos luego ejecutan la lgica de corte transversal antes de llamar los mtodos correspondiente de la super clase. JBoss AOP es un marco de trabajo para AOP. Utilizndolo puede crear asuntos de corte transversal utilizando mtodos y clases java convencionales. En terminologia de AOP cada asunto est representado por un aspecto que usted implementa utilizando un POJO simple. El comportamiento lo proporciona los mtodos dentro del aspecto llamado consejos. Estos consejos siguen ciertas reglas para su parmetro y retornan tiposy cualquier excepcin que presenten. Dentro de este marco de trabajo puede utilizar nociones convencionales orientadas a objetos tal como la herencia, encapsulacin y composicin para hacer que sus asuntos de corte transversal sean fciles de mantener. Los aspectos se aplican al cdigo utilizando un lenguaje de expresiones que le permite especificar los constructores, los mtodos e incluso los campos de destino. Puede cambiar rpidamente el comportamiento de mltiples clases modificando el archivo de configuracin. Este captulo contiene ejemplos, los cuales demuestran cmo utilizar JBoss AOP junto con el microcontenedor para crear y aplicar un aspecto de auditora al servicio de recursos humanos. El cdigo de auditora se puede poner dentro de la clase HRManager, pero llenara la clase con cdigo que no es relevante para su propsito principal, expandindola y haciendo ms dificil el mantenerla. El diseo del aspecto tambin proporciona modularidad, facilitando el auditar otras clases en el futuro, si el mbito del proyecto cambia. AOP tambin se puede utilizar para aplicar comportamiento adicional durante la fase de implementacin. Este ejemplo crear y enlazar un proxy a una instancia bean en un servicio bsico JNDI, permitiendo accederlo utilizando una bsqueda JNDI en lugar del controlador del microcontenedor. 5.1. Creacin de un aspecto El directorio examples/User_Guide/gettingStarted/auditAspect contiene todos los archivos necesarios para crear el aspecto. pom.xml src/main/java/org/jboss/example/aspect/AuditAspect.java Captulo 5. Agregar comportamiento con AOP 37 Ejemplo 5.1. POJO de ejemplo public class AuditAspect { private String logDir; private BufferedWriter out; public AuditAspect() { logDir = System.getProperty("user.dir") + "/log"; File directory = new File(logDir); if (!directory.exists()) { directory.mkdir(); } } public Object audit(ConstructorInvocation inv) throws Throwable { SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyyy-kkmmss"); Calendar now = Calendar.getInstance(); String filename = "auditLog-" + formatter.format(now.getTime()); File auditLog = new File(logDir + "/" + filename); auditLog.createNewFile(); out = new BufferedWriter(new FileWriter(auditLog)); return inv.invokeNext(); } public Object audit(MethodInvocation inv) throws Throwable { String name = inv.getMethod().getName(); Object[] args = inv.getArguments(); Object retVal = inv.invokeNext(); StringBuffer buffer = new StringBuffer(); for (int i=0; i < args.length; i++) { if (i > 0) { buffer.append(", "); } buffer.append(args[i].toString()); } if (out != null) { out.write("Method: " + name); if (buffer.length() > 0) { out.write(" Args: " + buffer.toString()); } if (retVal != null) { out.write(" Return: " + retVal.toString()); } out.write("\n"); out.flush(); } return retVal; } }
JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 38 Procedimiento 5.1. Creacin del POJO 1. El constructor chequea a ver si hay un directorio log en el directorio actual de trabajo y lo crea si no lo encuentra. 2. Luego se define un aviso. Se llama a este aviso cuando se llama al constructor de la clase de destino. Esto crea un nuevo archivo de registro dentro del directorio log para registrar la llamadas de mtodos realizadas en diferentes instancias de la clase destino en archivos separados. 3. Finalmente se define otro aviso. Este aviso aplica a cada llamada de mtodo realizada en la clase destino.El nombre del mtodo y los argumentos se almacenan junto con el valor de retorno. Esta informacin se utiliza para construir un registro de auditora y escribirlo en el archivo de registro actual. Cada aviso llama a inv.invokeNext(), el cual encadena los avisos si se ha aplicado ms de un asunto de corte transversal o para llamar el constructor/mtodo destino. Nota Cada aviso se implementa utilizando un mtodo que toma un objeto de invocacin como parmetro, presenta Throwable y retorna Object. En el momento del diseo no se sabe a qu constructores o mtodos se aplicarn estos avisos as que haga los tipos tan genricos como sea posible. Para compilar la clase y crear un archivo auditAspect.jar que lo puedan utilizar otros ejemplos, escriba mvn install desde el directorio auditAspect. 5.2. Configuracin del microcontenedor para AOP Antes de aplicar el aspecto de auditora al servicio de recursos humanos, se debe agregar un nmero de JARs a la ruta de clase de la extensin. Se encuentran en el sub-directorio lib de la distribucin client-aop que se encuentra en el directorio examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir: Captulo 5. Agregar comportamiento con AOP 39 Ejemplo 5.2. Listado del directorio examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir |-- client-1.0.0.jar |-- jboss-beans.xml |-- lib |-- auditAspect-1.0.0.jar |-- concurrent-1.3.4.jar |-- humanResourcesService-1.0.0.jar |-- javassist-3.6.0.GA.jar |-- jboss-aop-2.0.0.beta1.jar |-- jboss-aop-mc-int-2.0.0.Beta6.jar |-- jboss-common-core-2.0.4.GA.jar |-- jboss-common-core-2.2.1.GA.jar |-- jboss-common-logging-log4j-2.0.4.GA.jar |-- jboss-common-logging-spi-2.0.4.GA.jar |-- jboss-container-2.0.0.Beta6.jar |-- jboss-dependency-2.0.0.Beta6.jar |-- jboss-kernel-2.0.0.Beta6.jar |-- jbossxb-2.0.0.CR4.jar |-- log4j-1.2.14.jar |-- trove-2.1.1.jar `-- xercesImpl-2.7.1.jar |-- log `-- auditLog-18062010-122537 `-- run.sh Primero, se necesita lib/auditAspect-1.0.0.jar para crear una instancia del aspecto en tiempo de ejecucin con el fin de ejecutar la lgica. Luego el archivo jar para JBoss AOP (jboss-aop.jar) junto con sus dependencias javassist y trove, agrega la funcionalidad AOP. Finalmente, se necesita la jar jboss-aop-mc-int ya que contiene una definicin de esquema XML que le permite definir aspectos dentro de un descriptor de implementacin XML. Tambin contiene cdigo de integracin para crear dependencias entre beans normales y beans de aspecto dentro del microcontenedor, permitindole agregar comportamiento durante las fases de implementacin y de borrado de la implementacin. Ya que est utilizando Maven2 para montar la distribucin cliente-aop, debe agregar estos archivos JAR declarando las dependencias apropiadas en su archivo pom.xml y creando un descriptor de ensamblaje vlido. Puede ver un ejemplo de pom.xml en Ejemplo 5.3, Extracto de ejemplo pom.xml para AOP. Para realizar su construccin utilizando Ant, el procedimiento ser diferente. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 40 Ejemplo 5.3. Extracto de ejemplo pom.xml para AOP <dependency> <groupId>org.jboss.microcontainer.examples</groupId> <artifactId>jboss-oap</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.jboss.microcontainer.examples</groupId> <artifactId>javassist</artifactId> <version>3.6.0.GA</version> </dependency> <dependency> <groupId>org.jboss.microcontainer.examples</groupId> <artifactId>trove</artifactId> <version>2.1.1</version> </dependency> <dependency> <groupId>org.jboss.microcontainer.examples</groupId> <artifactId>jboss-aop-mc-int</artifactId> <version>2.0.0.Beta6</version> </dependency> 5.3. Aplicacin de un aspecto Ahora que tiene una distribucin vlida que contiene todo lo que necesitad, puede configurar jboss- beans.xml para aplicar el aspecto de auditora. Se encuentra en examples/User_Guide/gettingStarted/commandLineClient/target/client-aop.dir. <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="AspectManager" class="org.jboss.aop.AspectManager"> <constructor factoryClass="org.jboss.aop.AspectManager" factoryMethod="instance"/> </bean> <aop:aspect xmlns:aop="urn:jboss:aop-beans:1.0" name="AuditAspect" class="org.jboss.example.aspect.AuditAspect" method="audit" pointcut="execution(public org.jboss.example.service.HRManager->new(..)) OR execution(public * org.jboss.example.service.HRManager->*(..))"> </aop:aspect> ... </deployment>
Captulo 5. Agregar comportamiento con AOP 41 Procedimiento 5.2. Explicacin del cdigo para aplicar un aspecto 1. Antes de que pueda aplicar su aspecto a cualquier clase necesita crear una instancia de org.jboss.aop.AspectManager usando un elemento <bean>. Aqu se utiliza un mtodo de fbrica en lugar de llamar un constructor convencional ya que solo es necesario una instancia del AspectManager en la MVJ en tiempo de ejecucin. 2. Luego se crea una instancia de nuestro aspecto llamada AuditAspect, utilizando el elemento <aop:aspect>. Este se ve similar al elemento <bean> ya que tiene los atributos name y class que se utilizan de la misma manera. Sin embargo, tambin tiene los atributos method y pointcut que puede utilizar para aplicar o enlazar un consejo dentro del aspecto para los constructores y mtodos dentro de otras clases. Estos atributos enlazan el consejo de auditora a todos los constructores y mtodos pblicos dentro de la clase HRManager. Slo es necesario especificar el mtodo audit ya que ha sido sobrecargado dentro de la clase AuditAspect con diferentes parmetros. JBoss AOP sabe cul seleccionar en tiempo de ejecucin dependiendo de si se est realizando una invocacin de mtodo o constructor. Esta configuracin adicional es todo lo que se necesita para aplicar el aspecto de auditora en tiempo de ejecucin agregando un comportamiento de auditora al servicio Human Resources. Puede probar esto ejecutando el cliente utilizando el script run.sh. Se crea un directorio log al iniciar junto con el directorio lib cuando el microcontenedor crea el bean AuditAspect. Cada implementacin del servicio de recursos humanos hace que aparezca un nuevo archivo de registros dentro del directorio log. El archivo de registro contiene un registro de las llamadas realizadas del cliente al servicio. Se llama algo como auditLog-28112007-163902 y contiene salidas similares a Ejemplo 5.4, Ejemplo de la salida del registro AOP. Ejemplo 5.4. Ejemplo de la salida del registro AOP Method: getEmployees Return: [] Method: addEmployee Args: (Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860) Return: true Method: getSalary Args: (Santa Claus, null - Birth date unknown) Return: 10000 Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)] Method: isHiringFreeze Return: false Method: getEmployees Return: [(Santa Claus, 1 Reindeer Avenue, Lapland City - 25/12/1860)] Method: getSalaryStrategy Para borrar el comportamiento de auditora, comente los fragmentos relevantes de XML en el descriptor de implementacin y re-inicie la aplicacin. Aviso El orden de la implementacin s importa. Especificamente cada aspecto debe ser declarado antes de los beans a los que aplica, as que el microcontenedor los implementa en ese orden. Esto se debe a que es posible que el microcontenedor tenga que alterar el cdigo byte de la clase bean para agregar la lgica cross-cutting, antes de crear una instancia y almacena una referencia a esta en el controlador. Si ya se ha creado una instancia normal del bean entonces no es posible. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 42 5.4. Callbacks del ciclo de vida Adems de aplicar aspectos a los beans que instanciamos utilizando el microcontenedor tambin podemos agregar comportamiento durante el proceso de implementacin y de borrado de la implementacin. Tal como lo mencinamos en Seccin 4.3, Acceso directo, un bean atravieza varios estados diferentes cuando se implementa. Estos incluyen: NOT_INSTALLED el descriptor de implementacin que contiene el bean ha sido analizado sintcticamente junto con cualquier anotacin en el bean mismo. DESCRIBED cualquier dependencia que AOP ha creado ha sido agregada al bean y se han procesado las anotaciones personalizadas. INSTANTIATED se ha creado una instancia del bean. CONFIGURED se han inyectado las propiedades en el bean junto con cualquier otra referencia a los otros beans. CREATE se ha llamado al mtodo create, si est definido en el bean. START se ha llamado al mtodo start, si est definido en el bean. INSTALLED cualquier accin de instalacin personalizada que se defini en el descriptor de implementacin se ha ejecutado y est listo para acceder al bean. Importante Los estados CREATE y START estn includos por razones de legado. Esto le permite a los servicios que estaban implementados como MBeans en versiones anteriores de la plataforma empresarial el funcionar correctamente cuando se implementan como beans en la plataforma empresarial 5.1. Si no define ningn mtodo crear/inicar correspondientes en su bean, pasar derecho por estos estados. Estos estados representan el ciclo de vida del bean. Puede definir un nmero de callbacks para que se apliquen en cualquier momento utilizando un grupo adicional de elementos <aop>. <aop:lifecycle-describe> aplicado al entrar/salir del estado DESCRIBED Captulo 5. Agregar comportamiento con AOP 43 <aop:lifecycle-instantiate> aplicado al entrar/salir del estado INSTANTIATED <aop:lifecycle-configure> aplicado al entrar/salir del estado CONFIGURED <aop:lifecycle-create> aplicado al entrar/salir del estado CREATE <aop:lifecycle-start> aplicado al entrar/salir del estado START <aop:lifecycle-install> aplicado al entrar/salir del estado INSTALLED As como los elementos <bean> y <aop:aspect>, los elementos <aop:lifecycle-> contienen atributos name y class. El microcontenedor usa estos atributos para crear una instancia de la clase callback, nombrndola de manera que se pueda utilizar cuando los beans entren o salgan del estado relevante durante la implementacin y durante el borrado de la implementacin. Puede especificar cules beans son afectados por el callback utilizando el atributo clases como se puede ver en Ejemplo 5.5, Uso del atributo classes. Ejemplo 5.5. Uso del atributo classes <aop:lifecycle-install xmlns:aop="urn:jboss:aop-beans:1.0" name="InstallAdvice" class="org.jboss.test.microcontainer.support.LifecycleCallback" classes="@org.jboss.test.microcontainer.support.Install"> </aop:lifecycle-install>
Este cdigo especifica que la lgica adicional en la clase lifecycleCallback se aplica a cualquier clase de bean que est anotada con @org.jboss.test.microcontainer.support.Install antes de que entren y luego de que han dejado el estado INSTALLED. Para que la clase callback funcione, debe contener los mtodos install y uninstall que toman ControllerContext como parmetro, como se puede ver en Ejemplo 5.6, Mtodos de instalacin y desinstalacin. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 44 Ejemplo 5.6. Mtodos de instalacin y desinstalacin import org.jboss.dependency.spi.ControllerContext; public class LifecycleCallback { public void install(ControllerContext ctx) { System.out.println("Bean " + ctx.getName() + " is being installed"; } public void uninstall(ControllerContext ctx) { System.out.println("Bean " + ctx.getName() + " is being uninstalled"; } }
El mtodo install se llama durante la implementacin del bean y se llama al mtodo uninstall durante el borrado de la implementacin. Nota Aunque se est agregando comportamiento al proceso de implementacin y de borrado de la implementacin utilizando callbacks, AOP de ehcho no se utiliza aqu. La funcionalidad pointcut expression de JBoss AOP se utiliza para determinar a cules clases bean se aplican los comportamientos. 5.5. Agregar bsquedas de servicios por medio de JNDI Hasta ahora ha utilizado el microcontenedor para buscar referencias a instancias del bean que representan servicios. Esto no es ideal ya que requiere una referencia al kernel del microcontenedor antes de poder acceder al controlador. Esto se puede ver en Ejemplo 5.7, Bsqueda de referencias a los Beans. Captulo 5. Agregar comportamiento con AOP 45 Ejemplo 5.7. Bsqueda de referencias a los Beans private HRManager manager; private EmbeddedBootstrap bootstrap; private Kernel kernel; private KernelController controller; private final static String HRSERVICE = "HRService"; ... // Start JBoss Microcontainer bootstrap = new EmbeddedBootstrap(); bootstrap.run(); kernel = bootstrap.getKernel(); controller = kernel.getController(); ... ControllerContext context = controller.getInstalledContext(HRSERVICE); if (context != null) { manager = (HRManager) context.getTarget(); } El entregar referencias del kernel a todos los clientes que buscan un servicio es un riesgo de seguridad ya que proporciona un amplio acceso a la configuracin del microcontenedor. Para mayor seguridad aplique el patrn ServiceLocator y utilice una clase para realizar bsquedas de parte de los clientes. Incluso puede pasar las referencias del bean junto con sus nombres al ServiceLocator en el momento de la implementacin utilizando un callback del ciclo de vida. En ese escenario, el ServiceLocator puede buscarlos sin llegar a saber del microcontenedor. El borrado de la implementacin posteriormente borrara las referencias del bean del ServiceLocator para evitar ms bsquedas. No sera dificil es escribir su propia implementacin ServiceLocator. En integrar una ya existente tal como JBoss Naming Service (JBoss NS) es incluso ms rpido y tiene el beneficio adicional de cumplir con la especificacin de JNDI - Java Naming and Directory Interface. JNDI habilita a los clientes para acceder diferentes y posiblemente mltiples servicios de nombrado utilizando una API comn. Procedimiento 5.3. Escritura de su propia implementacin ServiceLocator 1. Primero cree una instancia de JBoss NS usando el microcontenedor. 2. Luego, agregue un callback del ciclo de vida para realizar el enlace y des-enlace de las referencias bean durante la implementacin y durante el borrado de la implementacin. 3. Marque las clases bean a las que desea enlazar sus referencias, utilizando anotaciones. 4. Ahora puede ubicar los beans en tiempo de ejecucin utilizando la expresin como se mostr anteriormente. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 46 Parte II. Conceptos avanzados con el microcontenedor Esta seccin aborda conceptos avanzados y muestra algunas funcionalidades interesantes del microcontenedor. Se asume que los ejemplos de cdigo en el resto del manual son ejemplos incompletos y es responsabilidad del programador el extrapolarlos y extenderlos como sea necesario. Parte II. Conceptos avanzados con el microcontenedor 47 Captulo 6. Modelos de componentes El JBoss Microcontainer funciona dentro de varios modelos de componentes POJO populares. Los componentes son programas de software re-utilizables que puede desarrollar y ensamblar fcilmente para crear aplicaciones sofisticadas. Una de las metas clave del microcontenedor es la integracin efectiva con estos modelos de componentes. Algunos modelos de componentes populares que se pueden utilizar con el microcontenedor son JMX, Spring y Guice. 6.1. Interacciones permitidas con los modelos de componentes Antes de discutir la interaccin como algunos de los modelos de componentes populares, es importante el comprender qu tipos de interacciones se permiten. JMX MBeans son un ejemplo de un modelo de componentes. Sus interacciones incluyen la ejecucin de operaciones MBean, referencia a atributos, el configurar atributos y la declaracin explcita de dependencias entre las MBeans nombradas. Las interacciones y comportamientos predeterminados en el microcontenedor son lo que normalmente obtiene de cualquier otro contenedor Inversin de Control (IoC del ingls >Inversion of Control) y es similar a la funcionalidad que los MBeans proporcionan, incluyendo simples invocaciones de mtodo para operaciones, setters/getters para los atributos y dependencias explcitas. 6.2. Un Bean sin dependencias Ejemplo 6.1, Descriptor de implementacin para un POJO simple muestra un descriptor de implementacin para un POJO simple sin dependencias. Este es el punto inicial para integrar el microcontenedor con Spring o Guice. Ejemplo 6.1. Descriptor de implementacin para un POJO simple <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="PlainPojo" class="org.jboss.demos.models.plain.Pojo"/> <beanfactory name="PojoFactory" class="org.jboss.demos.models.plain.Pojo"> <property name="factoryClass">org.jboss.demos.models.plain.PojoFactory</property> </beanfactory> </deployment> 6.3. Uso del microcontenedor con Spring JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 48 Ejemplo 6.2. Descriptor con soporte para Spring <beans xmlns="urn:jboss:spring-beans:2.0"> <!-- Adding @Spring annotation handler --> <bean id="SpringAnnotationPlugin" class="org.jboss.spring.annotations.SpringBeanAnnotationPlugin" /> <bean id="SpringPojo" class="org.jboss.demos.models.spring.Pojo"/> </beans>
El espacio de nombre del archivo es diferente del archivo del bean del microcontenedor. El espacio de nombre urn:jboss:spring-beans:2.0 apunta a su versin del puerto del esquema Spring, el cual describe el estilo Spring de su bean. El microcontenedor implementa los beans a manera opuesta de la nocin de fbrica de beans de Spring. Ejemplo 6.3. Uso de Spring con el microcontenedor public class Pojo extends AbstractPojo implements BeanNameAware { private String beanName; public void setBeanName(String name) { beanName = name; } public String getBeanName() { return beanName; } public void start() { if ("SpringPojo".equals(getBeanName()) == false) throw new IllegalArgumentException("Name doesn't match: " + getBeanName()); } }
Aunque el bean SpringPojo tiene una dependencia en la biblioteca de Spring causada por la implementacin de la interfaz BeanNameAware, su nico propsito es exponer e imitar algo del comportamiento del callback de Spring. Captulo 6. Modelos de componentes 49 El enfoque de Guice es el acomplamiento de tipos. Los beans Guice se generan y se configuran usando mdulos. Ejemplo 6.4. Descriptor de implementacin para la integracin Guice en el microcontenedor <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="GuicePlugin" class="org.jboss.guice.spi.GuiceKernelRegistryEntryPlugin"> <constructor> <parameter> <array elementClass="com.google.inject.Module"> <bean class="org.jboss.demos.models.guice.PojoModule"/> </array> </parameter> </constructor> </bean> </deployment>
Dos partes importantes de observar en este archivo son PojoModule y GuiceKernelRegistryEntryPlugin. PojoModule configura sus beans tal como en Ejemplo 6.5, Configuracin de Beans para Guice. GuiceKernelRegistryEntryPlugin proporciona integracin con el microcontenedor tal como se puede ver en Ejemplo 6.6, Integracin mock con el microcontenedor. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 50 Ejemplo 6.5. Configuracin de Beans para Guice public class PojoModule extends AbstractModule { private Controller controller; @Constructor public PojoModule(@Inject( bean = KernelConstants.KERNEL_CONTROLLER_NAME) Controller controller) { this.controller = controller; } protected void configure() { bind(Controller.class).toInstance(controller); bind(IPojo.class).to(Pojo.class).in(Scopes.SINGLETON); bind(IPojo.class).annotatedWith(FromMC.class). toProvider(GuiceIntegration.fromMicrocontainer(IPojo.class, "PlainPojo")); } }
Captulo 6. Modelos de componentes 51 Ejemplo 6.6. Integracin mock con el microcontenedor public class GuiceKernelRegistryEntryPlugin implements KernelRegistryPlugin { private Injector injector; public GuiceKernelRegistryEntryPlugin(Module... modules) { injector = Guice.createInjector(modules); } public void destroy() { injector = null; } public KernelRegistryEntry getEntry(Object name) { KernelRegistryEntry entry = null; try { if (name instanceof Class<?>) { Class<?> clazz = (Class<?>)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(clazz)); } else if (name instanceof Key) { Key<?> key = (Key<?>)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(key)); } } catch (Exception ignored) { } return entry; } }
Nota Se crea un Injector desde la clase Modules luego realiza una bsqueda en este para ver si hay beans que coincidan. Consulte Seccin 6.5, MBeans de legado y mezcla de diferentes modelos de componentes para encontrar mayor informacin sobre la declaracin y uso de MBeans de legado. 6.5. MBeans de legado y mezcla de diferentes modelos de componentes El ejemplo ms simple de mezclar diferentes modelos de contenido se puede ver en Ejemplo 6.7, JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 52 Inyeccin de un POJO en un MBean. Ejemplo 6.7. Inyeccin de un POJO en un MBean <server> <mbean code="org.jboss.demos.models.mbeans.Pojo" name="jboss.demos:service=pojo"> <attribute name="OtherPojo"><inject bean="PlainPojo"/></attribute> </mbean> </server> Para implementar MBeans por medio del microcontenedor debe escribir un manejador nuevo por completo para el modelo de componentes. Consulte system-jmx-beans.xml para obtener mayores detalles. El cdigo de este archivo se encuentra en el cdigo fuente del servidor de aplicaciones JBoss: sub-proyecto system-jmx. 6.6. Exponer POJOs como MBeans Ejemplo 6.8. Exponer un POJO existenete como un MBean <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="AnnotatedJMXPojo" class="org.jboss.demos.models.jmx.AtJmxPojo"/> <bean name="XmlJMXPojo" class="org.jboss.demos.models.mbeans.Pojo">
Este descriptor presenta un POJO existente como un MBean y lo registra en un servidor MBean. Para exponer un POJO como un MBean finalcelo con una anotacin @JMX asumiendo que ha importado org.jboss.aop.microcontainer.aspects.jmx.JMX. El bean se puede exponer directamente o en su propiedad. Captulo 6. Modelos de componentes 53 Ejemplo 6.9. Presentacin de un POJO como un MBean usando su propiedad <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="XMLLoginConfig" class="org.jboss.demos.models.old.XMLLoginConfig"/> <bean name="SecurityConfig" class="org.jboss.demos.models.old.SecurityConfig"> <property name="defaultLoginConfig"><inject bean="XMLLoginConfig"/></property> </bean> <bean name="SecurityChecker" class="org.jboss.demos.models.old.Checker"> <property name="loginConfig"><inject bean="jboss.security:service=XMLLoginConfig"/></property> <property name="securityConfig"><inject bean="jboss.security:service=SecurityConfig"/></property> </bean> </deployment>
Puede utilizar cualquiera de los tipos de bsqueda de inyeccin ya sea buscando un POJO simple u obteniendo un MBean del servidor MBean. Una de las opciones de inyeccin es utilizar la inyeccin de tipos, algunas veces llamada autowiring y se puede ver en Ejemplo 6.10, Autowiring. Ejemplo 6.10. Autowiring <deployment xmlns="urn:jboss:bean-deployer:2.0"> <bean name="FromGuice" class="org.jboss.demos.models.plain.FromGuice"> <constructor><parameter><inject bean="PlainPojo"/></parameter></constructor> <property name="guicePojo"><inject/></property> </bean> <bean name="AllPojos" class="org.jboss.demos.models.plain.AllPojos"> <property name="directMBean"><inject bean="jboss.demos:service=pojo"/></property> <property name="exposedMBean"><inject bean="jboss.demos:service=ExposedPojo"/></property> <property name="exposedMBean"><inject bean="jboss.demos:service=ExposedPojo"/></property> </bean> </deployment>
El bean FromGuice inyecta el bean Guice por medio de la correspondencia de tipos, en donde PlainPojo se inyecta con una inyeccin de nombres comn. Ahora puede probar a ver si el enlace JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 54 Guice funciona como se esperaba como se puede ver en Ejemplo 6.11, Prueba de la funcionalidad de Guice. Ejemplo 6.11. Prueba de la funcionalidad de Guice public class FromGuice { private IPojo plainPojo; private org.jboss.demos.models.guice.Pojo guicePojo; public FromGuice(IPojo plainPojo) { this.plainPojo = plainPojo; } public void setGuicePojo(org.jboss.demos.models.guice.Pojo guicePojo) { this.guicePojo = guicePojo; } public void start() { f (plainPojo != guicePojo.getMcPojo()) throw new IllegalArgumentException("Pojos are not the same: " + plainPojo + "!=" + guicePojo.getMcPojo()); } }
Ejemplo 6.11, Prueba de la funcionalidad de Guice solo proporciona un modelo de componentes alias. El alias es una funcionalidad trivial pero necesaria. Se debe introducir como un modelo nuevo de componentes dentro del microcontenedor con el fin de implementarlo como una dependencia verdadera. Los detalles de la implementacin se pueden ver en Ejemplo 6.12, Cdigo fuente de AbstractController. Ejemplo 6.12. Cdigo fuente de AbstractController <deployment xmlns="urn:jboss:bean-deployer:2.0"> <alias name="SpringPojo">springPojo</alias> </deployment>
Este descriptor mapea el nombre del SpringPojo al alias del springPojo. El beneficio de los aliases como verdaeros modelos de componentes es que el momento de la implementacin del bean se vuelve menos importante. El alias espera en un estado no-instalado hasta que el bean real lo dispara. Captulo 6. Modelos de componentes 55 Captulo 7. Inyeccin avanzada de dependencias y ldC Hoy en da la Inyeccin de Dependencias (ID), tambin llamada Inversin de Control (IdC), se encuentra en la parte central de muchos marcos de trabajo que adoptan la nocin de un contenedor o un modelo de componentes. En un captulo anterior abordamos los modelos de componentes. El kernel JBoss JMX, el precursor al microcontenedor, solo proporcionaba soporte ligero para ID/IdC , principalmente debido a las limitaciones del acceder los MBeans por medio del servidor MBeans. Sin embargo, con el nuevo modelo de componentes basados en POJO se encuentran disponibles varias nuevas e interesantes funcionalidades. Este captulo muestra la manera en que puede aplicar diferentes conceptos ID con la ayuda del microcotenedor JBoss. Estos conceptos se expresarn por medio del cdigo XML pero tambin puede aplicar la mayora de estas funcionalidades utilizando las anotaciones. 7.1. Fbrica de valores Una fbrica de valores es un bean, el cual tiene uno o ms mtodos dedicados a generar valores por usted. Consulte Ejemplo 7.1, Fbrica de valores. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 56 Ejemplo 7.1. Fbrica de valores <bean name="Binding" class="org.jboss.demos.ioc.vf.PortBindingManager"> <constructor> <parameter> <map keyClass="java.lang.String" valueClass="java.lang.Integer"> <entry> <key>http</key> <value>80</value> </entry> <entry> <key>ssh</key> <value>22</value> </entry> </map> </parameter> </constructor> </bean> <bean name="PortsConfig" class="org.jboss.demos.ioc.vf.PortsConfig"> <property name="http"><value-factory bean="Binding" method="getPort" parameter="http"/></property> <property name="ssh"><value-factory bean="Binding" method="getPort" parameter="ssh"/></property> <property name="ftp"> <value-factory bean="Binding" method="getPort"> <parameter>ftp</parameter> <parameter>21</parameter> </value-factory> </property> <property name="mail"> <value-factory bean="Binding" method="getPort"> <parameter>mail</parameter> <parameter>25</parameter> </value-factory> </property> </bean>
Ejemplo 7.2, PortsConfig muestra la manera en que el bean PortsConfig usa el bean de enlace para obtener sus valores por medio de la invocacin del mtodo getPort. Captulo 7. Inyeccin avanzada de dependencias y ldC 57 Ejemplo 7.2. PortsConfig public class PortBindingManager { private Map<String, Integer> bindings; public PortBindingManager(Map<String, Integer> bindings) { this.bindings = bindings; } public Integer getPort(String key) { return getPort(key, null); } public Integer getPort(String key, Integer defaultValue) { if (bindings == null) return defaultValue; Integer value = bindings.get(key); if (value != null) return value; if (defaultValue != null) bindings.put(key, defaultValue); return defaultValue; } }
7.2. Callbacks El descriptor que se puede ver en Ejemplo 7.3, Callbacks para reunir y filtrar beans le permite reunir todos los beans de un cierto tipo e incluso limitar el nmero de beans que coincidan. Junto con el descriptor en Ejemplo 7.3, Callbacks para reunir y filtrar beans, el cdigo Java que se puede ver en Ejemplo 7.4, Un analizador sintctico para reunir todos los editores muestra un Parser, el cual reune todos los Editores. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 58 Ejemplo 7.3. Callbacks para reunir y filtrar beans <bean name="checker" class="org.jboss.demos.ioc.callback.Checker"> <constructor> <parameter> <value-factory bean="parser" method="parse"> <parameter> <array elementClass="java.lang.Object"> <value>http://www.jboss.org</value> <value>SI</value> <value>3.14</value> <value>42</value> </array> </parameter> </value-factory> </parameter> </constructor> </bean> <bean name="editorA" class="org.jboss.demos.ioc.callback.DoubleEditor"/> <bean name="editorB" class="org.jboss.demos.ioc.callback.LocaleEditor"/> <bean name="parser" class="org.jboss.demos.ioc.callback.Parser"> <incallback method="addEditor" cardinality="4..n"/> <uncallback method="removeEditor"/> </bean> <bean name="editorC" class="org.jboss.demos.ioc.callback.LongEditor"/> <bean name="editorD" class="org.jboss.demos.ioc.callback.URLEditor"/>
Ejemplo 7.4. Un analizador sintctico para reunir todos los editores public class Parser { private Set<Editor> editors = new HashSet<Editor>(); ... public void addEditor(Editor editor) { editors.add(editor); } public void removeEditor(Editor editor) { editors.remove(editor); } }
Observe que incallback y uncallback usan el nombre del mtodo para buscar. Captulo 7. Inyeccin avanzada de dependencias y ldC 59 <incallback method="addEditor" cardinality="4..n"/> <uncallback method="removeEditor"/>
Un lmite inferior controla cuntos editores de hecho hacen que el bean progrese de un estado configurado: cardinality=4..n/> Eventualmente se crea Checker y corrige el analizador sintctico. Esto se ilustra en Ejemplo 7.5, El corrector para el analizador sintctico. Ejemplo 7.5. El corrector para el analizador sintctico public void create() throws Throwable { Set<String> strings = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); for (Object element : elements) strings.add(element.toString()); if (expected.equals(strings) == false) throw new IllegalArgumentException("Illegal expected set: " + expected + "!=" + strings); }
7.3. Modo de acceso del Bean Con el BeanAccessMode predeterminado no se inspeccionan los campos de un bean. Sin embargo, si especifica un BeanAccessMode diferente entonces los campos son accesibles como parte de las propiedades del bean. Consulte Ejemplo 7.6, Definiciones posibles para BeanAccessMode, Ejemplo 7.7, Configuracin de BeanAccessMode y Ejemplo 7.8, La clase FieldsBean para una implementacin. Ejemplo 7.6. Definiciones posibles para BeanAccessMode public enum BeanAccessMode { STANDARD(BeanInfoCreator.STANDARD), // Getters and Setters FIELDS(BeanInfoCreator.FIELDS), // Getters/Setters and fields without getters and setters ALL(BeanInfoCreator.ALL); // As above but with non public fields included }
Aqu un valor de cadena se configura como un campo de cadena privado: JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 60 Ejemplo 7.7. Configuracin de BeanAccessMode <bean name="FieldsBean" class="org.jboss.demos.ioc.access.FieldsBean" access- mode="ALL"> <property name="string">InternalString</property> </bean>
Ejemplo 7.8. La clase FieldsBean public class FieldsBean { private String string; public void start() { if (string == null) throw new IllegalArgumentException("Strings should be set!"); } }
7.4. Alias Bean Cada bean puede tener cualquier nmero de alias. Ya que los nombres de los componentes del microcontenedor se tratan como objetos, el tipo del alias no es limitado. Por defecto no se realiza un reemplazo de la propiedad del sistema; es necesario que establezca la etiqueta de reemplazo de manera explcita como se puede ver en Ejemplo 7.9, Un alias simple de Bean. Ejemplo 7.9. Un alias simple de Bean <bean name="SimpleName" class="java.lang.Object"> <alias>SimpleAlias</alias> <alias replace="true">${some.system.property}</alias> <alias class="java.lang.Integer">12345</alias> <alias><javabean xmlns="urn:jboss:javabean:2.0" class="org.jboss.demos.bootstrap.Main"/></alias> </bean>
7.5. Soporte para anotaciones XML (o metadatos) Una de las funcionalidades principales en el microcontenedor de JBoss es el soporte para AOP. Puede Captulo 7. Inyeccin avanzada de dependencias y ldC 61 utilizar aspectos AOP y beans simples combinadas de cualquier manera. Ejemplo 7.10, Interceptar un mtodo basado en una anotacin trata de interceptar una invocacin de mtodo con base en una anotacin. La anotacin puede provenir de cualquier lado. Puede ser una anotacin de clase verdadera o puede ser una anotacin agregada por medio de la configuracin xml. Ejemplo 7.10. Interceptar un mtodo basado en una anotacin <interceptor xmlns="urn:jboss:aop-beans:1.0" name="StopWatchInterceptor" class="org.jboss.demos.ioc.annotations.StopWatchInterceptor"/> <bind xmlns="urn:jboss:aop-beans:1.0" pointcut="execution(* @org.jboss.demos.ioc.annotations.StopWatchLog->*(..)) OR execution(* *- >@org.jboss.demos.ioc.annotations.StopWatchLog(..))"> <interceptor-ref name="StopWatchInterceptor"/> </bind> </interceptor>
Ejemplo 7.11, Un verdadero ejecutor anotado de clase and Ejemplo 7.12, Ejecutor simple con anotaciones XML muestra algunas maneras diferentes de implementar los ejecutores. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 62 Ejemplo 7.11. Un verdadero ejecutor anotado de clase <bean name="AnnotatedExecutor" class="org.jboss.demos.ioc.annotations.AnnotatedExecutor">
public class AnnotatedExecutor implements Executor { ... @StopWatchLog // <-- Pointcut match! public void execute() throws Exception { delegate.execute(); } }
Ejemplo 7.12. Ejecutor simple con anotaciones XML <bean name="SimpleExecutor" class="org.jboss.demos.ioc.annotations.SimpleExecutor"> <annotation>@org.jboss.demos.ioc.annotations.StopWatchLog</annotation> // <-- Pointcut match! </bean>
public class SimpleExecutor implements Executor { private static Random random = new Random(); public void execute() throws Exception { Thread.sleep(Math.abs(random.nextLong() % 101)); } }
Despus de agregar los beans invocadores del ejecutor, puede ver los ejecutores en accin durante el empleo, buscando salidas del registro tal como Ejemplo 7.13, Salida del registro del ejecutor. Captulo 7. Inyeccin avanzada de dependencias y ldC 63 Ejemplo 7.13. Salida del registro del ejecutor JBoss-MC-Demo INFO [15-12-2008 13:57:39] StopWatch - Invocation [org.jboss.demos.ioc.annotations.AnnotatedExecutor@4d28c7] start: 1229345859234 JBoss-MC-Demo INFO [15-12-2008 13:57:39] StopWatch - Invocation [org.jboss.demos.ioc.annotations.AnnotatedExecutor@4d28c7] time: 31 JBoss-MC-Demo INFO [15-12-2008 13:57:39] StopWatch - Invocation [org.jboss.demos.ioc.annotations.SimpleExecutor@1b044df] start: 1229345859265 JBoss-MC-Demo INFO [15-12-2008 13:57:39] StopWatch - Invocation [org.jboss.demos.ioc.annotations.SimpleExecutor@1b044df] time: 47 7.6. Autowire Autowiring o la inyeccin contextual, es una funcionalidad comn con con marcos de trabajo IdC. Ejemplo 7.14, Incluir y excluir con autowiring le muestra cmo utilizar o excluir beans con autowiring. Ejemplo 7.14. Incluir y excluir con autowiring <bean name="Square" class="org.jboss.demos.ioc.autowire.Square" autowire- candidate="false"/> <bean name="Circle" class="org.jboss.demos.ioc.autowire.Circle"/> <bean name="ShapeUser" class="org.jboss.demos.ioc.autowire.ShapeUser"> <constructor> <parameter><inject/></parameter> </constructor> </bean> <bean name="ShapeHolder" class="org.jboss.demos.ioc.autowire.ShapeHolder"> <incallback method="addShape"/> <uncallback method="removeShape"/> </bean> <bean name="ShapeChecker" class="org.jboss.demos.ioc.autowire.ShapesChecker"/> En ambos casos - ShapeUser y ShapeChecker - solo Circle se debe utilizar ya que Square se excluye en el enlace contextual. 7.7. Fbrica de beans Cuando quiere ms de una instancia de un bean en particular, necesita utilizar el patrn de fbrica del bean. El trabajo del microcontenedor es configurar e instalar la fbrica de beans como si fuera un bean simple. Luego necesita invocar el mtodo createBean de la fbrica de beans. Por defecto, el microcontenedor crea una instancia GenericBeanFactory, pero puede configurar su propia fbrica. La nica limitacin es que su firma y ganchos de configuracin son similares al de AbstractBeanFactory. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 64 Ejemplo 7.15. Fbrica de beans genricas <bean name="Object" class="java.lang.Object"/> <beanfactory name="DefaultPrototype" class="org.jboss.demos.ioc.factory.Prototype"> <property name="value"><inject bean="Object"/></property> </beanfactory> <beanfactory name="EnhancedPrototype" class="org.jboss.demos.ioc.factory.Prototype" factoryClass="org.jboss.demos.ioc.factory.EnhancedBeanFactory"> <property name="value"><inject bean="Object"/></property> </beanfactory> <beanfactory name="ProxiedPrototype" class="org.jboss.demos.ioc.factory.UnmodifiablePrototype" factoryClass="org.jboss.demos.ioc.factory.EnhancedBeanFactory"> <property name="value"><inject bean="Object"/></property> </beanfactory> <bean name="PrototypeCreator" class="org.jboss.demos.ioc.factory.PrototypeCreator"> <property name="default"><inject bean="DefaultPrototype"/></property> <property name="enhanced"><inject bean="EnhancedPrototype"/></property> <property name="proxied"><inject bean="ProxiedPrototype"/></property> </bean>
Consulte Ejemplo 7.16, BeanFactory extendido para ver el uso de un BeanFactory extendido. Captulo 7. Inyeccin avanzada de dependencias y ldC 65 Ejemplo 7.16. BeanFactory extendido public class EnhancedBeanFactory extends GenericBeanFactory { public EnhancedBeanFactory(KernelConfigurator configurator) { super(configurator); } public Object createBean() throws Throwable { Object bean = super.createBean(); Class clazz = bean.getClass(); if (clazz.isAnnotationPresent(SetterProxy.class)) { Set<Class> interfaces = new HashSet<Class>(); addInterfaces(clazz, interfaces); return Proxy.newProxyInstance( clazz.getClassLoader(), interfaces.toArray(new Class[interfaces.size()]), new SetterInterceptor(bean) ); } else { return bean; } } protected static void addInterfaces(Class clazz, Set<Class> interfaces) { if (clazz == null) return; interfaces.addAll(Arrays.asList(clazz.getInterfaces())); addInterfaces(clazz.getSuperclass(), interfaces); } private class SetterInterceptor implements InvocationHandler { private Object target; private SetterInterceptor(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if (methodName.startsWith("set")) throw new IllegalArgumentException("Cannot invoke setters."); return method.invoke(target, args); } } } JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 66 public class PrototypeCreator { ... public void create() throws Throwable { ValueInvoker vi1 = (ValueInvoker)bfDefault.createBean(); vi1.setValue("default"); ValueInvoker vi2 = (ValueInvoker)enhanced.createBean(); vi2.setValue("enhanced"); ValueInvoker vi3 = (ValueInvoker)proxied.createBean(); try { vi3.setValue("default"); throw new Error("Should not be here."); } catch (Exception ignored) { } } 7.8. Constructor de metadatos Bean Al utilizar el microcontenedor en su cdigo, use BeanMetaDataBuilder para crear y configurar los metadatos de su bean. Captulo 7. Inyeccin avanzada de dependencias y ldC 67 Ejemplo 7.17. BeanMetaDataBuilder <bean name="BuilderUtil" class="org.jboss.demos.ioc.builder.BuilderUtil"/> <bean name="BuilderExampleHolder" class="org.jboss.demos.ioc.builder.BuilderExampleHolder"> <constructor> <parameter><inject bean="BUExample"/></parameter> </constructor> </bean> Utilizando este concepto no expone su cdigo a ninguno de los detalles de implementacin del microcontenedor. public class BuilderUtil { private KernelController controller; @Constructor public BuilderUtil(@Inject(bean = KernelConstants.KERNEL_CONTROLLER_NAME) KernelController controller) { this.controller = controller; } public void create() throws Throwable { BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder("BUExample", BuilderExample.class.getName()); builder.addStartParameter(Kernel.class.getName(), builder.createInject(KernelConstants.KERNEL_NAME)); controller.install(builder.getBeanMetaData()); } public void destroy() { controller.uninstall("BUExample"); } }
7.9. ClassLoader personalizado En el microcontenedor puede definir un ClassLoader personalizado por bean. Al definir un cargador de clase para toda la implementacin, asegrese de no crear una dependencia cclica -- por ejemplo, un cargador de clase recin definido que dependa de s mismo. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 68 Ejemplo 7.18. Definicin de un cargador de clase por Bean <classloader><inject bean="custom-classloader:0.0.0"/></classloader> <!-- this will be explained in future article --> <classloader name="custom-classloader" xmlns="urn:jboss:classloader:1.0" export- all="NON_EMPTY" import-all="true"/> <bean name="CustomCL" class="org.jboss.demos.ioc.classloader.CustomClassLoader"> <constructor> <parameter><inject bean="custom-classloader:0.0.0"/></parameter> </constructor> <property name="pattern">org\.jboss\.demos\.ioc\..+</property> </bean> <bean name="CB1" class="org.jboss.demos.ioc.classloader.CustomBean"/> <bean name="CB2" class="org.jboss.demos.ioc.classloader.CustomBean"> <classloader><inject bean="CustomCL"/></classloader> </bean>
Ejemplo 7.19, Prueba del cargador de clase personalizado muestra una prueba para verificar que el bean CB2 usa un cargador de clase personalizado, el cual limita el mbito del paquete cargable. Ejemplo 7.19. Prueba del cargador de clase personalizado public class CustomClassLoader extends ClassLoader { private Pattern pattern; public CustomClassLoader(ClassLoader parent) { super(parent); } public Class<?> loadClass(String name) throws ClassNotFoundException { if (pattern == null || pattern.matcher(name).matches()) return super.loadClass(name); else throw new ClassNotFoundException("Name '" + name + "' doesn't match pattern: " + pattern); } public void setPattern(String regexp) { pattern = Pattern.compile(regexp); } }
7.10. Modo controlador Por defecto el microcontenedor usa el modo controlador AUTO. Lleva a los beans tan lejos como es posible con respecto a las dependencias. Pero hay otros dos modos: MANUAL y ON_DEMAND. Si el bean est marcado como ON_DEMAND entonces no se utilizar ni se instalar hasta que otro Captulo 7. Inyeccin avanzada de dependencias y ldC 69 bean dependa explcitamente de este. En el modo MANUAL, el usuario microcontenedor debe llevar al bean hacia adelante y atrs junto con el estado. Ejemplo 7.20. Modo controlador Bean <bean name="OptionalService" class="org.jboss.demos.ioc.mode.OptionalService" mode="On Demand"/> <bean name="OptionalServiceUser" class="org.jboss.demos.ioc.mode.OptionalServiceUser"/> <bean name="ManualService" class="org.jboss.demos.ioc.mode.ManualService" mode="Manual"/> <bean name="ManualServiceUser" class="org.jboss.demos.ioc.mode.ManualServiceUser"> <start> <parameter><inject bean="ManualService" fromContext="context" state="Not Installed"/></parameter> </start> </bean>
Nota Usando el atributo fromContext de la clase inject puede inyectar beans as como su representacin de componentes del microcontenedor inmodificables. Revise el cdigo de OptionalServiceUser y ManualServiceUser para ver cmo se utiliza la API del microcontenedor para el manejo de beans ON_DEMAND y MANUAL. 7.11. Ciclo Los beans pueden depender entre ellos en un ciclo. Por ejemplo, A depende de B en la construccin, pero B depende de A durante la configuracin. Debido a la separacin del ciclo de vida del estado detallado del microcontenedor, este problema se puede resolver fcilmente. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 70 Ejemplo 7.21. Separacin del ciclo de vida del Bean <bean name="cycleA" class="org.jboss.demos.ioc.cycle.CyclePojo"> <property name="dependency"><inject bean="cycleB"/></property> </bean> <bean name="cycleB" class="org.jboss.demos.ioc.cycle.CyclePojo"> <constructor><parameter><inject bean="cycleA" state="Instantiated"/></parameter></constructor> </bean> <bean name="cycleC" class="org.jboss.demos.ioc.cycle.CyclePojo"> <property name="dependency"><inject bean="cycleD"/></property> </bean> <bean name="cycleD" class="org.jboss.demos.ioc.cycle.CyclePojo"> <property name="dependency"><inject bean="cycleC" state="Instantiated"/></property> </bean>
7.12. Oferta y demanda Algunas veces as como con una inyeccin, es posible que una dependencia entre dos beans no sea aparente. Tales dependencias se deben expresar de manera clara tal como se puede ver en Ejemplo 7.22, Uso esttico del cdigo. Ejemplo 7.22. Uso esttico del cdigo <bean name="TMDemand" class="org.jboss.demos.ioc.demandsupply.TMDemander"> <demand>TM</demand> </bean> <bean name="SimpleTMSupply" class="org.jboss.demos.ioc.demandsupply.SimpleTMSupplyer"> <supply>TM</supply> </bean>
7.13. Instalaciones A medida que el bean se mueve a travs de diferentes estados es posible que quiera invocar algunos mtodos en otros beans o en el mismo bean. Ejemplo 7.23, Invocacin de mtodos en diferentes estados muestra cmo Entry invoca a los mtodos add y removeEntry del RepositoryManager pararegistrar y desregistrarse a s mismo. Captulo 7. Inyeccin avanzada de dependencias y ldC 71 Ejemplo 7.23. Invocacin de mtodos en diferentes estados <bean name="RepositoryManager" class="org.jboss.demos.ioc.install.RepositoryManager"> <install method="addEntry"> <parameter><inject fromContext="name"/></parameter> <parameter><this/></parameter> </install> <uninstall method="removeEntry"> <parameter><inject fromContext="name"/></parameter> </uninstall> </bean> <bean name="Entry" class="org.jboss.demos.ioc.install.SimpleEntry"> <install bean="RepositoryManager" method="addEntry" state="Instantiated"> <parameter><inject fromContext="name"/></parameter> <parameter><this/></parameter> </install> <uninstall bean="RepositoryManager" method="removeEntry" state="Configured"> <parameter><inject fromContext="name"/></parameter> </uninstall> </bean>
7.14. Imitacin perezosa Es posible que tenga una dependencia en un bean que se utilice con muy poca frecuencia, pero toma mucho tiempo en configurar. Puede utilizar la imitacin perezosa del bean que se demuestra en Ejemplo 7.24, Imitacin perezosa para resolver la dependencia. Cuando de hecho necesita el bean, invoque y use el bean destino esperando que para ese momento ya se haya instalalado. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 72 Ejemplo 7.24. Imitacin perezosa <bean name="lazyA" class="org.jboss.demos.ioc.lazy.LazyImpl"> <constructor> <parameter> <lazy bean="lazyB"> <interface>org.jboss.demos.ioc.lazy.ILazyPojo</interface> </lazy> </parameter> </constructor> </bean> <bean name="lazyB" class="org.jboss.demos.ioc.lazy.LazyImpl"> <constructor> <parameter> <lazy bean="lazyA"> <interface>org.jboss.demos.ioc.lazy.ILazyPojo</interface> </lazy> </parameter> </constructor> </bean> <lazy name="anotherLazy" bean="Pojo" exposeClass="true"/> <bean name="Pojo" class="org.jboss.demos.ioc.lazy.Pojo"/>
7.15. Ciclo de vida Por defecto el microcontenedor usa los mtodos create, start y destroy cuando avanza a travs de los variados estados. Sin embargo, es posible que no quiera que el microcontenedor los invoque. Por esta razn, se encuentra disponible una etiqueta ignore. Ejemplo 7.25. Ciclos de vida del Bean <bean name="FullLifecycleBean-3" class="org.jboss.demos.ioc.lifecycle.FullLifecycleBean"/> <bean name="FullLifecycleBean-2" class="org.jboss.demos.ioc.lifecycle.FullLifecycleBean"> <create ignored="true"/> </bean> <bean name="FullLifecycleBean-1" class="org.jboss.demos.ioc.lifecycle.FullLifecycleBean"> <start ignored="true"/> </bean>
Captulo 7. Inyeccin avanzada de dependencias y ldC 73 Captulo 8. El sistema virtual de archivos El duplicado del cdigo de manejo de recursos es un problema comn para los desarrolladores. En la mayora de los casos, el cdigo ayuda a determinar la informacin sobre un recurso en particular, el cual puede ser un archivo, un directorio o en el caso de una JAR, una URL remota. Otro problema de duplicacin es el cdigo para el procesamiento de ficheros anidados. Ejemplo 8.1, Problema de duplicacin de recursos ilustra el problema. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 74 Ejemplo 8.1. Problema de duplicacin de recursos Captulo 8. El sistema virtual de archivos 75 public static URL[] search(ClassLoader cl, String prefix, String suffix) throws IOException { Enumeration[] e = new Enumeration[]{ cl.getResources(prefix), cl.getResources(prefix + "MANIFEST.MF") }; Set all = new LinkedHashSet(); URL url; URLConnection conn; JarFile jarFile; for (int i = 0, s = e.length; i < s; ++i) { while (e[i].hasMoreElements()) { url = (URL)e[i].nextElement(); conn = url.openConnection(); conn.setUseCaches(false); conn.setDefaultUseCaches(false); if (conn instanceof JarURLConnection) { jarFile = ((JarURLConnection)conn).getJarFile(); } else { jarFile = getAlternativeJarFile(url); } if (jarFile != null) { searchJar(cl, all, jarFile, prefix, suffix); } else { boolean searchDone = searchDir(all, new File(URLDecoder.decode(url.getFile(), "UTF-8")), suffix); if (searchDone == false) { searchFromURL(all, prefix, suffix, url); } } } } return (URL[])all.toArray(new URL[all.size()]); } private static boolean searchDir(Set result, File file, String suffix) throws IOException { if (file.exists() && file.isDirectory()) { File[] fc = file.listFiles(); String path; for (int i = 0; i < fc.length; i++) { path = fc[i].getAbsolutePath(); if (fc[i].isDirectory()) { searchDir(result, fc[i], suffix); } else if (path.endsWith(suffix)) { JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 76 result.add(fc[i].toURL()); } } return true; } return false; } Tambin hay muchos problemas con el bloqueo de archivos en los sistemas Windows, lo cual ha forzado a los desarrolladores a copiar todos los ficheros de implementacin en vivo a otra ubicacin para prevenir el bloqueo de aquellos que se encuentran en las carpetas de implementacin (lo cual evitara el borrarlos y el borrado de la implementacin con base en el sistema de archivos). El bloqueo de archivos es un problema importante, cuya nica solucin sola ser el centralizar todo el cdigo de carga de recursos en un lugar. El proyecto VFS se cre para resolver todos estos problemas. VFS son las siglas en ingles de Virtual File System - sistema virtual de archivos. 8.1. API pblica VFS VFS se utiliza para dos propsitos principales tal como se puede ver en Usos para VFS. Usos para VFS navegacin simple de recursos API (del ingls Application Programmer Interface) del patrn del visitante Como se mencion anteriormente, en JDK simple, el manejo y navegacin de recursos es complejo. Siempre debe chequear el tipo de recurso y estos chequeos pueden llegar engorrosos. VFS abstrae los recursos en un solo tipo de recurso, VirtualFile. Captulo 8. El sistema virtual de archivos 77 Ejemplo 8.2. El tipo de recurso VirtualFile JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 78 public class VirtualFile implements Serializable { /** * Get certificates. * * @return the certificates associated with this virtual file */ Certificate[] getCertificates() /** * Get the simple VF name (X.java) * * @return the simple file name * @throws IllegalStateException if the file is closed */ String getName() /** * Get the VFS relative path name (org/jboss/X.java) * * @return the VFS relative path name * @throws IllegalStateException if the file is closed */ String getPathName() /** * Get the VF URL (file://root/org/jboss/X.java) * * @return the full URL to the VF in the VFS. * @throws MalformedURLException if a url cannot be parsed * @throws URISyntaxException if a uri cannot be parsed * @throws IllegalStateException if the file is closed */ URL toURL() throws MalformedURLException, URISyntaxException /** * Get the VF URI (file://root/org/jboss/X.java) * * @return the full URI to the VF in the VFS. * @throws URISyntaxException if a uri cannot be parsed * @throws IllegalStateException if the file is closed * @throws MalformedURLException for a bad url */ URI toURI() throws MalformedURLException, URISyntaxException /** * When the file was last modified * * @return the last modified time * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ long getLastModified() throws IOException /** * Returns true if the file has been modified since this method was last called * Last modified time is initialized at handler instantiation. * * @return true if modifed, false otherwise * @throws IOException for any error Captulo 8. El sistema virtual de archivos 79 */ boolean hasBeenModified() throws IOException /** * Get the size * * @return the size * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ long getSize() throws IOException /** * Tests whether the underlying implementation file still exists. * @return true if the file exists, false otherwise. * @throws IOException - thrown on failure to detect existence. */ boolean exists() throws IOException /** * Whether it is a simple leaf of the VFS, * i.e. whether it can contain other files * * @return true if a simple file. * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ boolean isLeaf() throws IOException /** * Is the file archive. * * @return true if archive, false otherwise * @throws IOException for any error */ boolean isArchive() throws IOException /** * Whether it is hidden * * @return true when hidden * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ boolean isHidden() throws IOException /** * Access the file contents. * * @return an InputStream for the file contents. * @throws IOException for any error accessing the file system * @throws IllegalStateException if the file is closed */ InputStream openStream() throws IOException /** * Do file cleanup. * * e.g. delete temp files */ JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 80 void cleanup() /** * Close the file resources (stream, etc.) */ void close() /** * Delete this virtual file * * @return true if file was deleted * @throws IOException if an error occurs */ boolean delete() throws IOException /** * Delete this virtual file * * @param gracePeriod max time to wait for any locks (in milliseconds) * @return true if file was deleted * @throws IOException if an error occurs */ boolean delete(int gracePeriod) throws IOException /** * Get the VFS instance for this virtual file * * @return the VFS * @throws IllegalStateException if the file is closed */ VFS getVFS() /** * Get the parent * * @return the parent or null if there is no parent * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ VirtualFile getParent() throws IOException /** * Get a child * * @param path the path * @return the child or <code>null</code> if not found * @throws IOException for any problem accessing the VFS * @throws IllegalArgumentException if the path is null * @throws IllegalStateException if the file is closed or it is a leaf node */ VirtualFile getChild(String path) throws IOException /** * Get the children * * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ List<VirtualFile> getChildren() throws IOException Captulo 8. El sistema virtual de archivos 81 /** * Get the children * * @param filter to filter the children * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed or it is a leaf node */ List<VirtualFile> getChildren(VirtualFileFilter filter) throws IOException /** * Get all the children recursively<p> * * This always uses {@link VisitorAttributes#RECURSE} * * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed */ List<VirtualFile> getChildrenRecursively() throws IOException /** * Get all the children recursively<p> * * This always uses {@link VisitorAttributes#RECURSE} * * @param filter to filter the children * @return the children * @throws IOException for any problem accessing the virtual file system * @throws IllegalStateException if the file is closed or it is a leaf node */ List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException /** * Visit the virtual file system * * @param visitor the visitor * @throws IOException for any problem accessing the virtual file system * @throws IllegalArgumentException if the visitor is null * @throws IllegalStateException if the file is closed */ void visit(VirtualFileVisitor visitor) throws IOException } Todas las operaciones del sistema de archivos de slo lectura estn disponibles adems de unas pocas opciones para limpiar o borrar el recurso. El manejo de la limpieza o el borrado se necesita al tratar con algunos archivos internos temporales tal como archivos creados para manejar jars anidadas. Para cambiar el manejo de recursos File o URL de JDK al nuevo VirtualFile necesita un VirtualFile raz, el cual los proporciona la clase VFS con la ayuda de la URL o el parmetro URI. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 82 Ejemplo 8.3. Uso de la clase VFS Captulo 8. El sistema virtual de archivos 83 public class VFS { /** * Get the virtual file system for a root uri * * @param rootURI the root URI * @return the virtual file system * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VFS getVFS(URI rootURI) throws IOException /** * Create new root * * @param rootURI the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile createNewRoot(URI rootURI) throws IOException /** * Get the root virtual file * * @param rootURI the root uri * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VirtualFile getRoot(URI rootURI) throws IOException /** * Get the virtual file system for a root url * * @param rootURL the root url * @return the virtual file system * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL is null */ static VFS getVFS(URL rootURL) throws IOException /** * Create new root * * @param rootURL the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile createNewRoot(URL rootURL) throws IOException /** * Get the root virtual file * * @param rootURL the root url * @return the virtual file * @throws IOException if there is a problem accessing the VFS * @throws IllegalArgumentException if the rootURL */ static VirtualFile getRoot(URL rootURL) throws IOException JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 84 /** * Get the root file of this VFS * * @return the root * @throws IOException for any problem accessing the VFS */ VirtualFile getRoot() throws IOException } Los tres mtodos diferentes se ven similares. getVFS createNewRoot getRoot getVFS retorna una instancia VFS pero todava no crea una instancia VirtualFile. Esto es importante ya que hay mtodos que ayudan con la configuracin de una instancia VFS (consulte la clase VFS API javadocs) antes de ordenarle que cree una raz VirtualFile. Por otro lado, los otros dos mtodos usan configuraciones predeterminadas para la creacin de root. La diferencia entre createNewRoot y getRoot es en los detalles de cach, los cuales abordaremos ms adelante. Ejemplo 8.4. Uso de getVFS URL rootURL = ...; // get root url VFS vfs = VFS.getVFS(rootURL); // configure vfs instance VirtualFile root1 = vfs.getRoot(); // or you can get root directly VirtualFile root2 = VFS.crateNewRoot(rootURL); VirtualFile root3 = VFS.getRoot(rootURL); Otra cosa til de la API VFS es su implementacin de un patrn visitante apropiado. Es muy simple el reunir recursos de manera recursiva, una tarea dificil de realizar con la carga de recursos JDK simple. Captulo 8. El sistema virtual de archivos 85 Ejemplo 8.5. Reunin de recursos de manera recursiva public interface VirtualFileVisitor { /** * Get the search attribues for this visitor * * @return the attributes */ VisitorAttributes getAttributes(); /** * Visit a virtual file * * @param virtualFile the virtual file being visited */ void visit(VirtualFile virtualFile); } VirtualFile root = ...; // get root VirtualFileVisitor visitor = new SuffixVisitor(".class"); // get all classes root.visit(visitor); 8.2. Arquitectura VFS Aunque la API pblica es bastante is quite intuitiva, los detalles de la implementacin real agregan complejidad. Es necesario explicar algunos conceptos en ms detalle. Cada vez que crea una instancia VFS tambin se crea su instancia correspondiente VFSContext. Esta creacin se realiza por medio de VFSContextFactory. Protocolos diferentes mapean a diferentes instancias VFSContextFactory. Por ejemplo, file/vfsfile mapea a FileSystemContextFactory mientras que zip/vfszip mapea a ZipEntryContextFactory. Cada vez que se crea una instancia VirtualFile tambin se crea su VirtualFileHandler correspondiente. Esta instancia VirtualFileHandler sabe cmo manejar diferentes tipos de recursos apropiadamente; el API VirtualFile solo delega invocaciones a su referencia VirtualFileHandler. La instancia VFSContext sabe cmo crear instancias VirtualFileHandler de acuerdo con el tipo de recurso. Por ejemplo, ZipEntryContextFactory crea ZipEntryContext, el cual luego crea ZipEntryHandler. 8.3. Implementaciones existentes Aparte de archivos, directorios (FileHandler) y ficheros zip (ZipEntryHandler), el microcontenedor tambin soporta otros casos ms avanzados. El primero es Assembled, el cual es similar a lo que Eclipse llama Linked Resources. Su propsito es tomar recursos ya existentes de diferentes rboles y "simular" un slo rbol de recursos. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 86 Ejemplo 8.6. Implementacin de VirtualFileHandlers reunidos AssembledDirectory sar = AssembledContextFactory.getInstance().create("assembled.sar"); URL url = getResource("/vfs/test/jar1.jar"); VirtualFile jar1 = VFS.getRoot(url); sar.addChild(jar1); url = getResource("/tmp/app/ext.jar"); VirtualFile ext1 = VFS.getRoot(url); sar.addChild(ext); AssembledDirectory metainf = sar.mkdir("META-INF"); url = getResource("/config/jboss-service.xml"); VirtualFile serviceVF = VFS.getRoot(url); metainf.addChild(serviceVF); AssembledDirectory app = sar.mkdir("app.jar"); url = getResource("/app/someapp/classes"); VirtualFile appVF = VFS.getRoot(url); app.addPath(appVF, new SuffixFilter(".class")); Otra implementacin son los archivos en-memoria. Esta implementacin surgi de la necesidad de manejar fcilmente bytes generados por AOP. En lugar de utilizar archivos temporales, puede poner bytes en VirtualFileHandlers en la memoria. Ejemplo 8.7. Implementacin de VirtualFileHandlers en memoria URL url = new URL("vfsmemory://aopdomain/org/acme/test/Test.class"); byte[] bytes = ...; // some AOP generated class bytes MemoryFileFactory.putFile(url, bytes); VirtualFile classFile = VFS.getVirtualFile(new URL("vfsmemory://aopdomain"), "org/acme/test/Test.class"); InputStream bis = classFile.openStream(); // e.g. load class from input stream 8.4. Ganchos de extensin Es fcil extender VFS con un nuevo protocolo, similar a lo que hicimos con Assembled y Memory. Todo lo que necesita es una combinacin de las implementaciones VFSContexFactory, VFSContext, VirtualFileHandler, FileHandlerPlugin y URLStreamHandler. La VFSContextFactory es trivial mientras que las otras dependen de la complejidad de su tarea. Puede implementar el acceso rar, tar, gzip, o incluso remote. Despus de implementar un nuevo protocolo, registre el nuevo VFSContextFactory con VFSContextFactoryLocator. 8.5. Funcionalidades Uno de los problemas principales que los desarrolladores del microcontenedor enfrentaron fue el uso Captulo 8. El sistema virtual de archivos 87 apropiado de los recursos anidados, ms especificamente de los archivos jar anidados: por ejemplo, implementaciones ear normales: gema.ear/ui.war/WEB-INF/lib/struts.jar. Con el fin de leer el contenido de struts.jar tenemos dos opciones: manejar los recursos en la memoria crear copias temporales de jars a nivel superior de manera recursiva La primera opcin es ms fcil de implementar, pero consume mucha memoria, lo cual requiere potencialmente que las aplicaciones grandes residan en la memoria. El otro enfoque deja atrs un gran nmero de archivos temporales, los cuales deben ser invisibles para el usuario y por lo tanto deben desaparecer despus del borrado de la implementacin. Considere el siguiente escenario: un usuario accede uns intstancia URL VFS, la cual apunta a algun recurso anidado. La manera en que el VFS simple manejara esto es re-creando toda la ruta desde el principio: desempacara los recursos anidados y de nuevo. Esto crea un gran nmero de archivos temporales. El microcontenedor evita esto utilizando VFSRegistry, VFSCache y TempInfo. Cuando solicita VirtualFile sobrer VFS (getRoot no createNewRoot), VFS le pide a la implementacin VFSRegistry que proporcione el archivo. El DefaultVFSRegistry existente primero chequea si extiste un VFSContext raz que coincida para la URI dada. Si s existe entonces DefaultVFSRegistry primero trata de navigar al TempInfo existente (enlace a un archivo temporal), regresando a la navegacin normal si no existe dicho archivo temporal. De esta manera reutiliza completamente cualuqier archivo temporal que ya hayan sido desempacados, ahorrando tiempo y espacio en el disco. Si no se encuentra un VFSContext que coincida en el cach entonces el cdigo crear una nueva entrada VFSCache y continuar con la navegacin predeterminada. El determinar la manera en que el VFSCache maneja las entradas VFSContext en cach depende de la implementacin utilizada. VFSCache es configurable por medio de VFSCacheFactory. Por defecto, nada va en el cach, pero hay unas pocas implementaciones VFSCache tiles existentes, utilizando algoritmos tal como Least Recently Used (LRU) o timed cache. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 88 Captulo 9. La capa ClassLoading JBoss siempre ha tenido una manera nica de tratar con la carga de clase y la nueva capa classloading que viene junto con el microcontenedor no es la excepcin. ClassLoading es una funcionalidad agregada que puede utilizar cuando prefiera la carga de clase no predeterminada. Con una mayor demanda por la carga de clase de estilo OSGi y un nmero de especificaciones nuevas de carga de clase Java en el horizonte, los cambios a la capa ClassLoading de EAP 5.1 son tiles y muy oportunos. La capa ClassLoading del microcontenedor es una capa de abstraccin. La mayora de los detalles se esconden detrs de mtodos privados y de paquetes privados sin comprometer la extensibilidad y funcionalidad disponibles por medio de las clases y mtodos pblicos que hacen el API. Esto significa que usted escribe cdigo frente a la poltica y no frente a los detalles del cargador de clase. El proyecto ClassLoader se divide en 3 sub-proyectos el cargador de clase - classloader la carga de la clase - classloading classloading-vfs classloader contiene una extensin java.lang.ClassLoader personalizada sin ninguna poltica de carga de clase especfica. Una poltica de carga de clase incluye el saber desde dnde carga y cmo cargar. Classloading es una extensin de los mecanismos de dependencia del microcontenedor. Su implementacin respaldada por VFS es classloading-vfs. Consulte Captulo 8, El sistema virtual de archivos para obtener mayor informacin sobre VFS. 9.1. ClassLoader La implementacin ClassLoader soporta polticas enchufables y es una clase final, se supone que no se debe alterar. Para escribir sus propias implementaciones ClassLoader, escriba una ClassLoaderPolicy, la cual proporciona una API ms simple para ubicar las clases y recursos y para especificar otras reglas asociadas con el cargador de clase. Para personalizar la carga de clase, instance una ClassLoaderPolicy y regstrela con un ClassLoaderSystem para crear un ClassLoader personalizado. Tambin puede crear un ClassLoaderDomain para realizar la particin en el ClassLoaderSystem. La capa ClassLoader tambin incluye la implementacin de cosas como el modelo DelegateLoader, la carga de clase, filtros de recursos y polticas de delegacin padre-hijo. El tiempo de ejecucin est habilitado para JMX para exponer la poltica utilizada para cada cargador de clase. Tambin proporciona estadsticas de carga de clase y mtodos de depuracin para ayudar a determinar desde dnde se cargan las cosas. Captulo 9. La capa ClassLoading 89 Ejemplo 9.1. La clase ClassLoaderPolicy La ClassLoaderPolicy controla la manera en que funciona la carga de clase. public abstract class ClassLoaderPolicy extends BaseClassLoaderPolicy { public DelegateLoader getExported() public String[] getPackageNames() protected List<? extends DelegateLoader> getDelegates() protected boolean isImportAll() protected boolean isCacheable() protected boolean isBlackListable() public abstract URL getResource(String path); public InputStream getResourceAsStream(String path) public abstract void getResources(String name, Set<URL> urls) throws IOException; protected ProtectionDomain getProtectionDomain(String className, String path) public PackageInformation getPackageInformation(String packageName) public PackageInformation getClassPackageInformation(String className, String packageName) protected ClassLoader isJDKRequest(String name) } }
Los siguientes dos ejemplos de ClassLoaderPolicy. El primero recupera los recursos con base en expresiones regulares, mientras que el segundo maneja los recursos encriptados. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 90 Ejemplo 9.2. ClassLoaderPolicy con soporte para expresiones regulares Captulo 9. La capa ClassLoading 91 public class RegexpClassLoaderPolicy extends ClassLoaderPolicy { private VirtualFile[] roots; private String[] packageNames; public RegexpClassLoaderPolicy(VirtualFile[] roots) { this.roots = roots; } @Override public String[] getPackageNames() { if (packageNames == null) { Set<String> exportedPackages = PackageVisitor.determineAllPackages(roots, null, ExportAll.NON_EMPTY, null, null, null); packageNames = exportedPackages.toArray(new String[exportedPackages.size()]); } return packageNames; } protected Pattern createPattern(String regexp) { boolean outside = true; StringBuilder builder = new StringBuilder(); for (int i = 0; i < regexp.length(); i++) { char ch = regexp.charAt(i); if ((ch == '[' || ch == ']' || ch == '.') && escaped(regexp, i) == false) { switch (ch) { case '[' : outside = false; break; case ']' : outside = true; break; case '.' : if (outside) builder.append("\\"); break; } } builder.append(ch); } return Pattern.compile(builder.toString()); } protected boolean escaped(String regexp, int i) { return i > 0 && regexp.charAt(i - 1) == '\\'; } public URL getResource(String path) { Pattern pattern = createPattern(path); for (VirtualFile root : roots) { URL url = findURL(root, root, pattern); if (url != null) return url; } return null; } JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 92 private URL findURL(VirtualFile root, VirtualFile file, Pattern pattern) { try { String path = AbstractStructureDeployer.getRelativePath(root, file); Matcher matcher = pattern.matcher(path); if (matcher.matches()) return file.toURL(); List<VirtualFile> children = file.getChildren(); for (VirtualFile child : children) { URL url = findURL(root, child, pattern); if (url != null) return url; } return null; } catch (Exception e) { throw new RuntimeException(e); } } public void getResources(String name, Set<URL> urls) throws IOException { Pattern pattern = createPattern(name); for (VirtualFile root : roots) { RegexpVisitor visitor = new RegexpVisitor(root, pattern); root.visit(visitor); urls.addAll(visitor.getUrls()); } } private static class RegexpVisitor implements VirtualFileVisitor { private VirtualFile root; private Pattern pattern; private Set<URL> urls = new HashSet<URL>(); private RegexpVisitor(VirtualFile root, Pattern pattern) { this.root = root; this.pattern = pattern; } public VisitorAttributes getAttributes() { return VisitorAttributes.RECURSE_LEAVES_ONLY; } public void visit(VirtualFile file) { try { String path = AbstractStructureDeployer.getRelativePath(root, file); Matcher matcher = pattern.matcher(path); if (matcher.matches()) Captulo 9. La capa ClassLoading 93 urls.add(file.toURL()); } catch (Exception e) { throw new RuntimeException(e); } } public Set<URL> getUrls() { return urls; } } }
RegexpClassLoaderPolicy usa un mecanismo simplistico para encontrar los recursos que coinciden. Las implementaciones del mundo real seran ms completas y elegantes. public class RegexpService extends PrintService { public void start() throws Exception { System.out.println(); ClassLoader cl = getClass().getClassLoader(); Enumeration<URL> urls = cl.getResources("config/[^.]+\\.[^.]{1,4}"); while (urls.hasMoreElements()) { URL url = urls.nextElement(); print(url.openStream(), url.toExternalForm()); } } }
El servicio de expresiones regulares usa el patrn de la expresin regular config/[^.]+\\.[^.]{1,4} para listar los recursos bajo el directorio config// . La longitud del sufijo es limitado de tal manera que los nombres de archivos tal como excluded.properties se ignorarn. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 94 Ejemplo 9.3. ClassLoaderPolicy con soporte para codificacin public class CrypterClassLoaderPolicy extends VFSClassLoaderPolicy { private Crypter crypter; public CrypterClassLoaderPolicy(String name, VirtualFile[] roots, VirtualFile[] excludedRoots, Crypter crypter) { super(name, roots, excludedRoots); this.crypter = crypter; } @Override public URL getResource(String path) { try { URL resource = super.getResource(path); return wrap(resource); } catch (IOException e) { throw new RuntimeException(e); } } @Override public InputStream getResourceAsStream(String path) { InputStream stream = super.getResourceAsStream(path); return crypter.crypt(stream); } @Override public void getResources(String name, Set<URL> urls) throws IOException { super.getResources(name, urls); Set<URL> temp = new HashSet<URL>(urls.size()); for (URL url : urls) { temp.add(wrap(url)); } urls.clear(); urls.addAll(temp); } protected URL wrap(URL url) throws IOException { return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile(), new CrypterURLStreamHandler(crypter)); } }
Ejemplo 9.3, ClassLoaderPolicy con soporte para codificacin muestra cmo encriptar JARs. Puede configurar cules recursos codificar especificando un filtro apropiado. Aqu todo est encriptado a excepcin del contenido del directorio META-INF/. Captulo 9. La capa ClassLoading 95 public class EncryptedService extends PrintService { public void start() throws Exception { ClassLoader cl = getClass().getClassLoader(); URL url = cl.getResource("config/settings.txt"); if (url == null) throw new IllegalArgumentException("No such settings.txt."); InputStream is = url.openStream(); print(is, "Printing settings:\n"); is = cl.getResourceAsStream("config/properties.xml"); if (is == null) throw new IllegalArgumentException("No such properties.xml."); print(is, "\nPrinting properties:\n"); } }
Este servicio imprime el contenido de dos archivos de configuracin. Muestra que se esconde la decodificacin de cualquier recurso encriptado detrs de la capa de carga de clase. Para probar esto apropiadamente puede encriptar el mdulo de poltica usted mismo o puede utilizar uno que ya est encriptado. Para poner esto en accin es necesario que uan apropiadamente EncryptedService con ClassLoaderSystem y los programas de implementacin. Ms adelante en este captulo abrodamos el particionamiento del ClassLoaderSystem. 9.2. ClassLoading En lugar de utilizar la abstraccin ClassLoader directamente puede crear mdulos ClassLoading, los cuales contienen declaraciones de dependencias ClassLoader. Una vez se especifican las dependencias se construyen las ClassLoaderPolicys y se conectan de manera respectiva. Para facilitar la definicin de los ClassLoaders antes de que existan, la abstraccin incluye un modelo ClassLoadingMetaData. El ClassLoadingMetaData se puede presentar como un objeto administrado dentro del nuevo servicio de perfil JBoss EAP. Esto le ayuda a los administradores de sistemas a tratar con los detalles de la poltica abstracta en lugar de los detalles de la implementacin. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 96 Ejemplo 9.4. ClassLoadingMetaData presentada como un objeto administrado public class ClassLoadingMetaData extends NameAndVersionSupport { /** The serialVersionUID */ private static final long serialVersionUID = -2782951093046585620L; /** The classloading domain */ private String domain; /** The parent domain */ private String parentDomain; /** Whether to make a subdeployment classloader a top-level classloader */ private boolean topLevelClassLoader = false; /** Whether to enforce j2se classloading compliance */ private boolean j2seClassLoadingCompliance = true; /** Whether we are cacheable */ private boolean cacheable = true; /** Whether we are blacklistable */ private boolean blackListable = true; /** Whether to export all */ private ExportAll exportAll; /** Whether to import all */ private boolean importAll; /** The included packages */ private String includedPackages; /** The excluded packages */ private String excludedPackages; /** The excluded for export */ private String excludedExportPackages; /** The included packages */ private ClassFilter included; /** The excluded packages */ private ClassFilter excluded; /** The excluded for export */ private ClassFilter excludedExport; /** The requirements */ private RequirementsMetaData requirements = new RequirementsMetaData(); /** The capabilities */ private CapabilitiesMetaData capabilities = new CapabilitiesMetaData(); ... setters & getters
Captulo 9. La capa ClassLoading 97 Ejemplo 9.5, API ClassLoading definida en XML y Ejemplo 9.6, API ClassLoading definida en Java muestran la API ClassLoading definida en XML y Java respectivamente. Ejemplo 9.5. API ClassLoading definida en XML <classloading xmlns="urn:jboss:classloading:1.0" name="ptd-jsf-1.0.war" domain="ptd-jsf-1.0.war" parent-domain="ptd-ear-1.0.ear" export-all="NON_EMPTY" import-all="true" parent-first="true"/>
Ejemplo 9.6. API ClassLoading definida en Java ClassLoadingMetaData clmd = new ClassLoadingMetaData(); if (name != null) clmd.setDomain(name + "_Domain"); clmd.setParentDomain(parentDomain); clmd.setImportAll(true); clmd.setExportAll(ExportAll.NON_EMPTY); clmd.setVersion(Version.DEFAULT_VERSION);
Puede agregar ClassLoadingMetaData a su implementacin ya sea programticamente o declarativamente por medio de jboss-classloading.xml. Ejemplo 9.7. Agregar ClassLoadingMetaData por medio de jboss-classloading.xml <classloading xmlns="urn:jboss:classloading:1.0" domain="DefaultDomain" top-level-classloader="true" export-all="NON_EMPTY" import-all="true"> </classloading> El DefaultDomain se comparte entre todas las aplicaciones que no definen sus propios dominios. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 98 Ejemplo 9.8. Aislamiento tpico a nivel de dominio <classloading xmlns="urn:jboss:classloading:1.0" domain="IsolatedDomain" export-all="NON_EMPTY" import-all="true"> </classloading> Ejemplo 9.9. Aislamiento con un padre especfico <classloading xmlns="urn:jboss:classloading:1.0" domain="IsolatedWithParentDomain" parent-domain="DefaultDomain" export-all="NON_EMPTY" import-all="true"> </classloading>
Ejemplo 9.10. No cumple con los requerimientos de j2seClassLoadingCompliance <classloading xmlns="urn:jboss:classloading:1.0" parent-first="false"> </classloading>
Las implementaciones .war usan este mtodo por defecto. En lugar de realizar buqeudas de padres primero por defecto primero chequea sus propios recursos. Ejemplo 9.11. Implementacin tpica OSGi <classloading xmlns="urn:jboss:classloading:1.0"> <requirements> <package name="org.jboss.dependency.spi"/> </requirements> <capabilities> <package name="org.jboss.cache.api"/> <package name="org.jboss.kernel.spi"/> </capabilities> </classloading> Captulo 9. La capa ClassLoading 99 Ejemplo 9.12. Importing and Exporting Whole Modules and Libraries, Rather than Fine- Grained Packages <classloading xmlns="urn:jboss:classloading:1.0"> <requirements> <module name="jboss-reflect.jar"/> </requirements> <capabilities> <module name="jboss-cache.jar"/> </capabilities> </classloading>
Tambin puede mezclar los requerimientos y los tipos de funcionalidades usando paquetes y mdulos. El sub-proyecto de carga de clase usa una implementacin muy pequea del patrn recurso-visitante. En el proyecto ClassLoader, la conexin entre implementacin y carga de clase se realiza por medio de la clase Module, la cual mantiene toda la informacin requerida para aplicar restricciones apropiadamente en el patrn del visitante tal como los filtros. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 100 Ejemplo 9.13. Las interfaces ResourceVisitor y ResourceContext public interface ResourceVisitor { ResourceFilter getFilter(); void visit(ResourceContext resource); } public interface ResourceContext { URL getUrl(); ClassLoader getClassLoader(); String getResourceName(); String getClassName(); boolean isClass(); Class<?> loadClass(); InputStream getInputStream() throws IOException; byte[] getBytes() throws IOException; }
Para usar el mdulo, instancie su instancia ResourceVisitor y psela al mtodo Module::visit. Esta funcionalidad se utiliza en el marco d etrabajo de la implementacin para indexar los usos de anotacions en las implementaciones. 9.3. Carga de clase VFS Esros ejemplos proporcionan una implementacin de la ClassLoaderPolicy que usa un proyecto de sistema de archivos virtual JBoss para cargar clases y recursos. Puede utilizar esta idea directamente o en conjunto con un marco de trabajo de carga de clase. Opcionalmente puede configurar sus mdulos dentro de la configuracin del microcontenedor. Captulo 9. La capa ClassLoading 101 Ejemplo 9.14. Programa de implementacin del mdulo de carga de clases <deployment xmlns="urn:jboss:bean-deployer:2.0"> <classloader name="anys-classloader" xmlns="urn:jboss:classloader:1.0" import- all="true" domain="Anys" parent-domain="DefaultDomain"> <capabilities> <package name="org.jboss.test.deployers.vfs.reflect.support.web"/> </capabilities> <root>${jboss.tests.url}</root> </classloader> <bean name="AnyServlet" class="org.jboss.test.deployers.vfs.reflect.support.web.AnyServlet"> <classloader><inject bean="anys-classloader:0.0.0"/></classloader> </bean> </deployment>
La clase VFSClassLoaderFactory transforma el programa de implementacin XML en un VFSClassLoaderPolicyModule, el cual luego crea la instacia real del ClassLoader. Luego puede utilizar directamente esta nueva instancia ClassLoader con sus beans. Nota VFSClassLoaderFactory extiende ClassLoadingMetaData as que todos los ejemplos relacionados con ClassLoadingMetaData aplican en este caso tambin. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 102 Captulo 10. Marco de trabajo de la implementacin virtual El nuevo Marco d etrabajo de la implementacin virtual (VDF del ingls Virtual Deployment Framework) es una manera mejorada de administrar los programas de implementacin en el microcontenedor. Este captulo detalla algunas de sus funcionalidades ms tiles. 10.1. Manejo agnstico de tipos de implementacin El tipo tradicional de implementacin virtual se basa en clases que ya existen en un espcio de clase o dominio compartido. En este caso, el producto final es un nuevo servicio instalado en el servidor desde el cliente principal. La manera tradicional de lograr esto es cargar un archivo del programa de implementacin. El nuevo VDF simplifica este proceso pasando los bytes y serialindolos en una instancia Deployment. El otro tipo de implementacin, el cual extiende el primero, es una implementancin basada en el sistema simple de archivos, respaldado po el microcontenedor VFS. Este enfoque se describe con ms detalle en Captulo 8, El sistema virtual de archivos. 10.2. Separacin del reconocimiento de la estructura de la lgica del ciclo de vida de la implementacin Con el fin de realizar cualquier trabajo real encima de una implementacin primero debe comprender su estructura incluyendo sus rutas de clase y la ubicacin de sus metadatos. La ubicacin de los metadatos incluye los archivos de configuracin tal como my-jboss-beans.xml, web.xml, ejb-jar.xml. Las rutas de clase son races del cargador de clase tal como WEB- INF/classes o myapp.ear/lib. Teniendo esta estructura en mente puede proceder al manejo de la implementacin. Ciclo de vida de una implementacin tpica 1. El MainDeployer le pasa la implementacin al grupo de StructuralDeployers para un reconocimiento y recibe un contexto de implementacin. 2. Luego, el MainDeployer le pasa el contexto de implementacin que resulta a los Deployers para que el Deployer apropiado lo maneje. De esta manera, el MainDeployer es un agente con la responsibilidad de decidir qu programas de implementacin utilizar. En el caso de una implementacin virtual o programtica, una informacin StructureMetaData predeterminada ya existente lee la informacin de la estructura y la maneja de una de las maneras que se explic en Manejo de la informacin StructuredMetaData. Manejo de la informacin StructuredMetaData Implementaciones basadas en VFS el reconocimiento de la estructura se re-enva a un grupo de StructureDeployers. estructuras definidas de la especificacin JEE tenemos implementaciones StructureDeployer que coinciden: EarStructure Captulo 10. Marco de trabajo de la implementacin virtual 103 WarStructure JarStructure DeclarativeStructures busca el archivo META-INF/jboss-structure.xml dentro de su implementacin y lo analiza sintcticamente para construir un StructureMetaData apropiado. FileStructures solo reconoce los archivos de configuracin conocidos tal como -jboss-beans.xml o - service.xml. Ejemplo 10.1. Un ejemplo de jboss-structure.xml <structure> <context comparator="org.jboss.test.deployment.test.SomeDeploymentComparatorTop"> <path name=""/> <metaDataPath> <path name="META-INF"/> </metaDataPath> <classpath> <path name="lib" suffixes=".jar"/> </classpath> </context> </structure> En el caso de EarStructure, primero reconozca una implementacin a nivel superior y luego procese recursivamente las sub-implementaciones. Puede implementar un StructureDeployer personalizado con la ayuda de la clase genrica GroupingStructure proporcionada por la interfaz genrica StructureDeployer. Despus de tener una estructura de implementacin reconocida se la puede pasar a los programas de implementacin reales. El objeto Deployers sabe cmo encargarse de los programas de implementacin reales, utilizando una cadena de programas de implementacin por DeploymentStage. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 104 Ejemplo 10.2. Etapas de la implementacin public interface DeploymentStages { /** The not installed stage - nothing is done here */ DeploymentStage NOT_INSTALLED = new DeploymentStage("Not Installed"); /** The pre parse stage - where pre parsing stuff can be prepared; altDD, ignore, ... */ DeploymentStage PRE_PARSE = new DeploymentStage("PreParse", NOT_INSTALLED); /** The parse stage - where metadata is read */ DeploymentStage PARSE = new DeploymentStage("Parse", PRE_PARSE); /** The post parse stage - where metadata can be fixed up */ DeploymentStage POST_PARSE = new DeploymentStage("PostParse", PARSE); /** The pre describe stage - where default dependencies metadata can be created */ DeploymentStage PRE_DESCRIBE = new DeploymentStage("PreDescribe", POST_PARSE); /** The describe stage - where dependencies are established */ DeploymentStage DESCRIBE = new DeploymentStage("Describe", PRE_DESCRIBE); /** The classloader stage - where classloaders are created */ DeploymentStage CLASSLOADER = new DeploymentStage("ClassLoader", DESCRIBE); /** The post classloader stage - e.g. aop */ DeploymentStage POST_CLASSLOADER = new DeploymentStage("PostClassLoader", CLASSLOADER); /** The pre real stage - where before real deployments are done */ DeploymentStage PRE_REAL = new DeploymentStage("PreReal", POST_CLASSLOADER); /** The real stage - where real deployment processing is done */ DeploymentStage REAL = new DeploymentStage("Real", PRE_REAL); /** The installed stage - could be used to provide valve in future? */ DeploymentStage INSTALLED = new DeploymentStage("Installed", REAL); } La etapas de implementacin pre-existentes se mapean a los estados del controlador incorporado del microcontenedor. Proporcionan una vista cntrica del ciclo de vida de la implementacin de los estados del controlador genrico. Dentro de los programas de implementacin, la implementacin se convierte en el componente DeploymentControllerContext del microcontenedor. La mquina de estado del microcontenedor maneja las dependencias. Las implementaciones se manejan secuencialmente por etapa de implementacin. Para cada porgrama de implementacin se maneja todo el orden de la jerarqua implementada usando la propiedad parent- first del programa de implementacin. Esta propiedad se configura como true por defecto. Tambin puede especificar los niveles de jerarqua que el programa de implementacin maneja. Puede seleccionar all, top level, components only o no components. La manera en que el microcontendor maneja los modelos de componentes y el manejo de las Captulo 10. Marco de trabajo de la implementacin virtual 105 La manera en que el microcontendor maneja los modelos de componentes y el manejo de las dependencias tambin aplica aqu. Si hay dependencias no resueltas entonces la implementacin empezar en el estado actual, potencialmente reportando un error si el estado actual no es el estado requerido. El agregar un nuevo programa de implementacin se logra extendiendo uno de los muchos programas de implementacin de ayuda que existen. Algunos programas de implementaciin de hecho necesitan una implementacin respaldada por VFS mientras que otros pueden utilizar una implementacin general. En la mayora de los casos los programas de instalacin de anlisis sintctico son los que necesitan respaldo de VFS. Aviso Tambin tenga en cuenta que los programas de implementacin ejecutan recursivamente en toda implementacin, sub-implementacin y componentes. Su cdigo necesita determinar tan pronto como sea posible en el proceso, si el programa de implementacin debe manejar la implementacin actual o no. Ejemplo 10.3. Programa de implementacin simple, el cual presenta informacin sobre su implementacin public class StdioDeployer extends AbstractDeployer { public void deploy(DeploymentUnit unit) throws DeploymentException { System.out.println("Deploying unit: " + unit); } @Override public void undeploy(DeploymentUnit unit) { System.out.println("Undeploying unit: " + unit); } } Agregue esta descripcin en uno de los archivos -jboss-beans.xml en el directorio deployers/ en el servidor de aplicaciones JBoss y el bean MainDeployerImpl reconocer este programa de implementacin por medio del manejo callback loC del microcontenedor. Ejemplo 10.4. Descriptor de implementacin simple <bean name="StdioDeployer" class="org.jboss.acme.StdioDeployer"/> 10.3. Control de flujo natural en forma de anexos VDF incluye un mecanismo llamado anexos -attachments, el cual facilita el paso de la informacin de un programa de implementacin al siguiente. Los anexos se implementan como un java.util.Map con mejoras, cuyas entradas representan un anexo. Algunos programas de implementacin son productores mientras que otros son consumidores. El JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 106 mismo programa de implementacin tambin puede realizar ambas funciones. Algunos programas de implementacin crean metadatos o instancias de funcionalidades ponindolos en el mapa de anexos. Otros programas de implementacin solo declaran su necesidad de estos anexos y toman los datos del mapa de anexos, antes de realizar trabajo adicional en esos datos. El orden natural se refiere a la manera en que los porgramas de implementacin se ordenan. Un orden natural comn usa los trminos relativos antes y despus. Sin embargo, con el mecanismo de anexos en uso puede ordenar los programas de implementacin de acuerdo a la manera en que producen y/o consumen los anexos. Cada anexo tiene una llave y los programas de implementacin pasan las llaves a los anexos que producen. Si el programa de implementacin produce un anexo entonces se llama a la llave output. Si el programa de implementacin consume un anexo entonces esa llave se llama input. Los programas de implementacin tienen entradas ordinarias y entradas requeridas. Las entradas ordinarias slo se utilizan para ayudar a determinar el orden natural. Las entradas requeridas tambin ayudan a determinar el orden, pero tambin tienen otra funcin. Ayudan a determinar si el programa de implementacin de hecho es relevante para la implementacin dada, chequeando a ver si existe un anexo correspondiente a esa entrada requerida en el mapa de anexos. Aviso Aunque se soporta el ordenamiento relativo, este se considera como mala prctica y es posible que no haya soporte para este en lanzamientos futuros. 10.4. Detalles de la implementacin y del cliente, usuario y uso del servidor Estas funcionalidades esconden los detalles de la implementacin, lo cual hace que el uso sea menos propenso a errores y al mismo tiempo optimiza el proceso de desarrollo. La meta es que los clientes solo vean una API de desarrollo mientras que los desarrolladores vean un DeploymentUnit y los detalles de la implementacin del servidor se encuentren en un DeploymentContext. Solo se presenta la informacin necesaria en un nivel en particular del ciclo de vida de la implementacin. Ya mencionamos los componentes como parte del manejo de la jerarqua de los desarrolladores. Aunque la implementacin y sub-implementacin a nivel superior son una representacin natural de la jerarqua de la estructura de la implementacin, los componentes son un nuevo concepto VDF. La idea de los componentes es que tengan un mapeo 1:1 con el ControllerContexts dentro del microcontenedor. Consulte Por qu los componentes mapean 1:1 con los ControllerContexts para ver las razones que respaldan esta afirmacin. Por qu los componentes mapean 1:1 con los ControllerContexts Nombrado El nombre de la unidad del componente es el mismo que el nombre del ControllerContext. get*Scope() and get*MetaData() retorna el mismo contexto MDR que el microcontenedor utilizar para esa instancia. Captulo 10. Marco de trabajo de la implementacin virtual 107 IncompleteDeploymentException (IDE) Con el fin de que el IDE imprima las dependencias que faltan en una implementacin, necesita saber los nombres del ControllerContext. descubre el nombre reuniendo los nombres de las DeploymentUnit's componentes en los programas de implementacin de componentes que los especifican tal como los mtodos BeanMetaDataDeployer o setUseUnitName() en AbstractRealDeployer. 10.5. Mquina de estado nico Todos los componentes del microcontenedor son manejados por un solo punto de entrada o una sola mquina de estado. Las implemtaciones no son la excepcin. Puede sacar ventaja de esta funcionalidad utilizando el archivo de configuracin jboss- dependency.xml en sus implementaciones. Ejemplo 10.5. jboss-dependency.xml <dependency xmlns="urn:jboss:dependency:1.0"> <item whenRequired="Real" dependentState="Create">TransactionManager</item> (1) <item>my-human-readable-deployment-alias</item> (2) </dependency> Note las llamadas artificiales en el XML: (1) y (2). (1) muestra cmo describir la dependencia en otro servicio. Este ejemplo requiere el crear un TransactionManager antes de que la implementacin se encuentre en la etapa 'real'. (2) es un poco ms complejo ya que le falta informacin adicional. Por defecto, los nombres de las implementaciones dentro del microcontenedor son nombres URI, lo cual hace que el escribirlos a mano sea un proceso propenso a errores. As que con el fin de declarar dependencias fcilmente en otras implementaciones, necesita un mecanismo de alias para evitar nombres URI. Puede agregar un archivo de texto simple llamado aliases.txt en su implementacin. Cada lnea del archivo contiene un alias, dndole al fichero de implementacin uno o ms nombres simples utilizados para referirse a este. 10.6. Escaneo de clases en busca de anotaciones Las especificaciones JEE actuales reducen el nmero de archivos de configuracin, pero ahora se requiere que el contenedor realice la mayora del trabajo utilizando @annotations. Con el fin de obtener informacin sobre @annotation, los contenedores deben escanear las clases. Este escaneo crea una penalidad en el rendimiento. Sin embargo con el fin de reducir la cantidad de escaneo, el microcontenedor proporciona otro gancho descriptor por medio de jboss-scanning.xml. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 108 Ejemplo 10.6. jboss-scanning.xml <scanning xmlns="urn:jboss:scanning:1.0"> <path name="myejbs.jar"> <include name="com.acme.foo"/> <exclude name="com.acme.foo.bar"/> </path> <path name="my.war/WEB-INF/classes"> <include name="com.acme.foo"/> </path> </scanning> Este ejemplo muestra una descripcin simple de rutas relativas para incluir o excluir cuando se escanea en busca de informacin de metadatos anotados para Java Enterprise Edition versin 5y posteriores. Captulo 10. Marco de trabajo de la implementacin virtual 109 Historial de revisiones Revisin 5.1.0-3.400 2013-10-31 Rdiger Landmann Rebuild with publican 4.0.0 Revisin 5.1.0-3 2012-07-18 Anthony Towns Rebuild for Publican 3.0 Revisin 5-1 Wed Sep 15 2010 Misty Stanley-Jones JBPAPP-5076 - Arreglar los ejemplos y sus leyendas Se cambi el nmero de la versin en relacin con los requerimientos de la versin. Revisado para JBoss Enterprise Application Platform 5.1.0.GA. JBoss Enterprise Application Platform 5 Manual del usuario de JBoss Microcontainer 110
ChatGPT Millionaire 2024 - Bot-Driven Side Hustles, Prompt Engineering Shortcut Secrets, and Automated Income Streams that Print Money While You Sleep. The Ultimate Beginner’s Guide for AI Business
ChatGPT Side Hustles 2024 - Unlock the Digital Goldmine and Get AI Working for You Fast with More Than 85 Side Hustle Ideas to Boost Passive Income, Create New Cash Flow, and Get Ahead of the Curve
Ultimate Snowflake Architecture for Cloud Data Warehousing: Architect, Manage, Secure, and Optimize Your Data Infrastructure Using Snowflake for Actionable Insights and Informed Decisions (English Edition)
Microsoft Excel Guide for Success: Transform Your Work with Microsoft Excel, Unleash Formulas, Functions, and Charts to Optimize Tasks and Surpass Expectations [II EDITION]
Excel 2023 for Beginners: A Complete Quick Reference Guide from Beginner to Advanced with Simple Tips and Tricks to Master All Essential Fundamentals, Formulas, Functions, Charts, Tools, & Shortcuts
Microsoft PowerPoint Guide for Success: Learn in a Guided Way to Create, Edit & Format Your Presentations Documents to Visual Explain Your Projects & Surprise Your Bosses And Colleagues | Big Four Consulting Firms Method