Anda di halaman 1dari 113

Mark Newton Ale Justin

JBoss Enterprise Application


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>

<parameter>file:/Users/newtonm/jbossmc/microcontainer/trunk/docs/examples/User_Gui
de/gettingStarted/commandLineClient/target/client-
cl.dir/otherLib/humanResourcesService-1.0.0.jar</parameter>
</constructor>
</bean>
<bean name="customCL" class="java.net.URLClassLoader">
<constructor>
<parameter>
<array>
<inject bean="URL"/>
</array>
</parameter>
</constructor>
</bean>
<bean name="HRService" class="org.jboss.example.service.HRManager">
<classloader><inject bean="customCL"/></classloader>
<!-- <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>



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>

<parameter>file:/Users/newtonm/jbossmc/microcontainer/trunk/docs/examples/User_G
uide/gettingStarted/commandLineClient/target/client-
cl.dir/otherLib/humanResourcesService-1.0.0.jar</parameter>
</constructor>
</bean>
<bean name="customCL" class="java.net.URLClassLoader">
<constructor>
<parameter>
<array>
<inject bean="URL"/>
</array>
</parameter>
</constructor>
</bean>
...
</deployment>



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">

<annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(exposedInterface=org.jb
oss.demos.models.mbeans.PojoMBean.class, registerDirectly=true)</annotation>
</bean>
<bean name="ExposedPojo" class="org.jboss.demos.models.jmx.Pojo"/>
<bean name="AnnotatedExposePojo"
class="org.jboss.demos.models.jmx.ExposePojo">
<constructor>
<parameter><inject bean="ExposedPojo"/></parameter>
</constructor>
</bean>
</deployment>



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>



public class StopWatchInterceptor implements Interceptor {
...
public Object invoke(Invocation invocation) throws Throwable
{
Object target = invocation.getTargetObject();
long time = System.currentTimeMillis();
log.info("Invocation [" + target + "] start: " + time);
try
{
return invocation.invokeNext();
}
finally
{
log.info("Invocation [" + target + "] time: " + (System.currentTimeMillis() -
time));
}
}
}



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>



<classloading xmlns="urn:jboss:classloading:1.0">
<requirements>
<package name="si.acme.foobar"/>
<module name="jboss-reflect.jar"/>
</requirements>
<capabilities>
<package name="org.alesj.cl"/>
<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

Anda mungkin juga menyukai