Vous êtes sur la page 1sur 8

davidmarco.

es

http://www.davidmarco.es/blog/entrada.php?id=239

davidmarco.es
Inicio Blog Sobre m Tutoriales Contacto

Introduccin a EJB 3.1 (I)


Publicado el 08 de Marzo de 2011
Con este artculo comienza un tutorial que describe el estandar EJB 3.1 de manera introductoria. El tutorial contiene tanto material terico como prctico, de manera que segn se vayan introduciendo nuevos conceptos se irn reflejando en cdigo. Es muy recomendable que antes de seguir leyendo visites el siguiente anexo donde se explica como poner en marcha un entorno de desarrollo compatible con EJB 3.1, de manera que puedas seguir todos los ejemplos que se van a presentar en el tutorial, as como desarrollar los tuyos propios. La siguiente lista muestra el contenido de los primeros 6 artculos de los que constar el tutorial. Esta lista se actualizar si se publica contenido adicional: 1. 2. 3. 4. 5. 6. Introduccin a EJB y primer ejemplo Stateless Session Beans y Stateful Session Beans Singletons y Message-Driven Beans Persistencia Servicios que ofrece el contenedor (1 parte) Servicios que ofrece el contenedor (2 parte)

Con todo esto dicho, comencemos!

1.1 QUE SON LOS ENTERPRISE JAVABEANS? EJB (Enterprise JavaBeans) es un modelo de programacin que nos permite construir aplicaciones Java mediante objetos ligeros (como POJO's). Cuando construimos una aplicacin, son muchas las responsabilidades que se deben tener en cuenta, como la seguridad, transaccionalidad, concurrencia, etc. El estandar EJB nos permite centrarnos en el cdigo de la lgica de negocio del problema que deseamos solucionar y deja el resto de responsabilidades al contenedor de aplicaciones donde se ejecutar la aplicacin.

1.2 EL CONTENEDOR DE APLICACIONES Un contenedor de aplicaciones es un entorno (en si mismo no es ms que una aplicacin) que provee los servicios comunes a la aplicacion que deseamos ejecutar, gestionndolos por nosotros. Dichos servicios incluyen la creacin/mantenimiento/destruccin de nuestros objetos de negocio, as como los servicios mencionados en el punto anterior, entre otros. Aunque el contenedor es responsable de la gestin y uso de dichos recursos/servicios, podemos interacturar con l para que nuestra aplicacin haga uso de los servicios que se ofrecen (normalmente mediante metadados, como se ver a lo largo del tutorial). Una vez escrita nuestra aplicacin EJB, podemos desplegarla en cualquier contenedor compatible con EJB, beneficiandonos de toda el trabajo tras bastidores que el contenedor gestiona por nosotros. De esta manera la lgica de negocio se mantiene independiente de otro cdigo que pueda ser necesario, resultando en cdigo que es ms fcil de escribir y mantener (adems de ahorrarnos mucho trabajo).

1.3 LA ESPECIFICACIN EJB 3.1 La especificacin EJB 3.1 es parte de la plataforma JavaEE 6, desarrollada y mantenida por Sun Microsystems (ahora parte de Oracle Corporation). JavaEE 6 provee diversas API's para la construccin de aplicaciones empresariales, entre ellas EJB, JPA, JMS, y JAX-WS. Cada una de ellas se centra en un area especfica, resolviendo as problemas concretos. Adems, cada API/especificacin est preparada para funcionar en compaia de las dems de forma nativa, y por tanto en su conjunto son una solucin perfectamente vlida para desarrollar una aplicacin end-to-end (de principio a fin). Desde la versin 3.0, EJB no impone ninguna restriccin ni obligacin a nuestros objetos de negocio de implementar una API en concreto. Dicho de otro modo, podemos escribir dichos objetos de negocio usando POJO's, facilitando entre otras cosas la reutilizacin de componentes y la tarea de testearlos. Como se ha dicho, los POJO's son faciles de testear (siempre que estn bien diseados). Al final de este primer artculo se ver un sencillo ejemplo de programacin de un EJB mediante Test-Driven Development (Desarrollo Dirigido por Tests). TDD es una metodologa de desarrollo en la cual cada bloque de cdigo est respaldado por uno o ms tests que han sido escritos con anterioridad. De manera muy resumida, TDD nos permite enfocar de manera efectiva el problema que deseamos resolver de la siguiente manera: - Escribimos un test que define que queremos hacer. - Ejecutamos el test y este falla (puesto que an no hay lgica de negocio, o lo que es lo mismo, como queremos hacerlo). - Escribimos la lgica de negocio que hace pasar el test (la solucin ms simple posible).

1 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

- Mejoramos la lgica de negocio gradualmente, ejecutando el test despus de cada mejora para verificar que no hemos roto nada. Escribir el test antes que la lgica de negocio y mantenerlo lo ms simple posible nos obliga a escribir cdigo independiente de otro cdigo, con responsabilidades bien definidas (en resumen, buen cdigo). Usado de forma correcta, TDD permite crear sistemas que son escalables, y con niveles de bugs muy bajos. TDD es un tema tan amplio en si mismo que no tiene cabida en este tutorial (a excepcin del citado ejemplo que veremos al final del artculo y que servir solamente para demostrar que el modelo EJB es un buen modelo de programacin), y en el que te animo que profundices si no lo conoces; las ventajas que ofrece para escribir cdigo de calidad son muchas, independientemente del uso de EJB o no. Por otro lado, el uso de POJO's para encapsular nuestra lgica de negocio nos proporciona un modelo simple que es altamente reutilizable (recuerda que la reutilizacin de clases es un concepto bsico y esencial en programacin orientada a objetos). Debes tener en cuenta que un POJO no actuar como un componente EJB hasta que haya sido empaquetado, desplegado en un contenedor EJB y accedido por dicho contenedor (por ejemplo a peticin de un usuario). Una vez que un POJO definido como EJB haya sido desplegado en el contenedor, se convertir en uno de los tres siguientes componentes (dependiendo del como lo hayamos definido): - Session Bean - Message-Driven Bean - Entity Bean Veamos una breve descripcin de cada tipo de componente (en captulos posteriores se explicar cada tipo de componente con ms detalle).

1.4 SESSION BEANS Los Session Beans (Beans de Sesin) son los componentes que contienen la lgica de negocio que requieren los clientes de nuestra aplicacin. Son accedidos a travs de un proxy (tambin llamado vista, trmino que utilizar en adelante) tras realizar una solicitud al contenedor. Tras dicha solicitud, el cliente obtiene una vista del Session Bean, pero no el Session Bean real. Esto permite al contenedor realizar ciertas operaciones sobre el Session Bean real de forma transparente para el cliente (como gestionar su ciclo de vida, solicitar una instancia a otro contenedor trabajando en paralelo, etc). Los componentes Session Bean pueden ser de tres tipos: - Stateless Session Beans - Stateful Session Beans - Singletons Stateless Session Beans (SLSB - Beans de Sesin sin Estado) son componentes que no requieren mantener un estado entre diferentes invocaciones. Un cliente debe asumir que diferentes solicitudes al contenedor de un mismo SLSB pueden devolver vistas a objetos diferentes. Dicho de otra manera, un SLSB puede ser compartido (y probablemente lo ser) entre varios clientes. Por todo esto, los SLSB son creados y destruidos a discreccin del contenedor, y puesto que no mantienen estado son muy eficientes a nivel de uso de memoria y recursos en el servidor. Stateful Session Beans (SFSB - Beans de Sesin con Estado), al contrario que SLSB, si que mantienen estado entre distintas invocaciones realizadas por el mismo cliente. Esto permite crear un estado conversacional (como el carrito de la compra en una tienda online, que mantiene los objetos que hemos aadido mientras navegamos por las diferentes pginas), de manera que acciones llevadas a cabo en invocaciones anteriores son tenidas en cuenta en acciones posteriores. Un SFSB es creado justo antes de la primera invocacin de un cliente, mantenido ligado a ese cliente, y destruido cuando el cliente invoque un mtodo en el SFSB que est marcado como finalizador (tambin puede ser destruido por timeout de sesin). Son menos eficientes a nivel de uso de memoria y recursos en el servidor que los SLSB. Los Singleton son un nuevo tipo de Session Bean introducido en EJB 3.1. Un Singleton es un componente que puede ser compartido por muchos clientes, de manera que una y solo una instancia es creada. A nivel de eficiencia en uso de memoria y recursos son indiscutblemente los mejores, aunque su uso est restringido a resolver ciertos problemas muy especficos.

1.5 MESSAGE-DRIVEN BEANS Message-Driven Beans (MDB - Beans Dirigidos por Mensajes) son componentes de tipo listener que actuan de forma asncrona. Su misin es la de consumir mensajes (por ejemplo eventos que se producen en la aplicacin), los cuales pueden gestionar directamente o enviar (derivar) a otro componente. Los MDB actuan sobre un proveedor de mensajera, por ejemplo Java Messaging System (JMS es adems soportado de forma implcita por la especificacion EJB). Al igual que los Stateless Session Beans, los Message-Driven Beans no mantienen estado entre invocaciones.

1.6 ENTITY BEANS

2 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

Los Entity Beans (EB - Beans de Entidad) son representaciones de datos almacenados en una base de datos, siempre en forma de POJO's. El encargado de gestionar los EB es EntityManager, un servicio que es suministrado por el contenedor y que est incluido en la especificacin Java Persistence API (JPA - API de Persistencia en Java). JPA es parte de EJB desde la versin 3.0 de esta ltima. Para saber ms sobre JPA, puedes visitar un tutorial anterior publicado en esta misma web en la siguiente direccin. Al contrario que los Session Beans y los Message-Driven Beans, los Entity Beans no son componentes del lado del servidor. En otras palabras, no trabajamos con una vista del componente, si no con el componente real.

1.6 EJB Y TEST-DRIVEN DEVELOPMENT Para terminar este primer artculo, dejemos de lado la teora y escribamos una sencilla aplicacin EJB para ir abriendo el apetito. Para poder seguir este y futuros ejemplos, debes tener en marcha un entorno compatible con EJB 3.1 (aunque la mayora de los ejemplos, incluido este, funcionarn en un contenedor compatible con EJB 3.0). Por otro lado, todo el cdigo se ajusta al estandard EJB 3.1 (no se usarn extensiones exclusivas de un contenedor concreto). Sin embargo, ten presente que las indicaciones relativas a la creacin del proyecto, despliegue, y ejecucin de los ejemplos estarn condicionadas por el entorno concreto que se ha puesto en marcha mediante el anexo que acompaa este tutorial; si tu entorno es diferente, ciertas acciones (como los opciones de mens a ejecutar en tu IDE) sern otras. Como se ha indicado en el punto 1.3, este ejemplo de desarrollar de manera puntual mediante Test-Driven Development. En los prximos artculos solo se mostrar cdigo EJB, que es al fin y al cabo el tema a tratar en este turorial. As mismo, los pasos para crear un proyecto o como desplegarlo en el contenedor EJB se omitirn en artculos posteriores. Para comenzar inicia Eclipse (si an no lo has hecho) y crea un nuevo proyecto EJB: File > New > EJB Project Dale un nombre al nuevo proyecto y asegrate tanto de seleccionar en el desplegable 'Target runtime' un contenedor compatible con EJB como de seleccionar la versin 3.1 en el desplegable 'EJB module version'. Haz click en el botn 'Finish' para crear el proyecto. Ahora es el momento de crear un test que defina y respalde nuestro primer EJB. Lo primero es crear una carpeta dentro del proyecto donde almacenaremos todos los tests que escribamos. En la pestaa 'Project Explorer' haz click con el botn derecho sobre el proyecto EJB y selecciona: New > Source Folder Introduce el nombre del directorio en el campo 'Folder name' (utiliza un nombre descriptivo, como 'tests') y haz click en el botn 'Finish'. Si expandes el proyecto EJB (con la flecha negra que hay a la izquierda del nombre) vers que el nuevo directorio se ha creado correctamente. Ahora vamos a crear la clase donde escribiremos los tests para nuestro EJB. Haz click con el botn derecho sobre el directorio de tests y selecciona: New > Other En la ventana que te aparecer selecciona: Java > JUnit > JUnit Test Case En la ventana de creacin de un test de JUnit selecciona la opcin 'New JUnit 4 test', introduce el nombre del paquete donde deseas alojar la clase en el campo 'Package' (muy recomendado) y escribe un nombre para la clase de tests. En mi caso, el nombre del paquete ser 'es.davidmarco.ejb.slsb' y el nombre de la clase de tests 'PrimerEJBTest'. Haz click en el botn 'Finish'; si es el primer tests que escribes para el proyecto (como es nuestro caso) aparecer una ventana donde Eclipse nos informa que la librera JUnit no est incluida en el classpath. Seleccionamos la opcin 'Perform the following action: Add JUnit4 library to the build path' (Realizar la siguiente accin: aadir la libreria JUnit 4 al path de construccin) y haz click en el botn 'OK'. Hecho esto, ya podemos escribir nuestro primer (y de momento nico) test:

package es.davidmarco.ejb.slsb; import org.junit.Test; import static org.junit.Assert.*; public class PrimerEJBTest { @Test public void testSaluda() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola usuario", ejb.saluda("usuario")); } }

El test (un mtodo que debe ser void, no aceptar parmetros, y estar anotado con la anotacin de JUnit @Test) declara las intenciones (el contrato) del cdigo que estamos diseando: crear un objeto de la clase PrimerEJB con un mtodo saluda() que acepte un argumento de tipo String y devuelva un mensaje con el formato 'Hola

3 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

argumento'. Aqu empezamos a ver las ventajas de EJB: podemos testear nuestro cdigo de negocio directamente, sin tener que desplegar el componente EJB en un contenedor y entonces hacer una llamada a este, con toda la parafernalia que esto requiere. Y ahora si (por fin) vamos a escribir nuestro primer EJB. Nuestra clase de negocio ira en un paquete con el mismo nombre que el utilizado para almacenar las clase de tests, pero en una carpeta diferente. De esta manera mantenemos ambos tipos de clases separadas fsicamente en disco (por motivos de organizacin y por claridad), pero accesibles gracias a que virtualmente pertenecen al mismo paquete, y por tanto entre ellos hay visibilidad de tipo package-default (esto puede resultarnos til si necesitamos, por ejemplo, acceder desde la clase de tests a mtodos en las respectivas clases de negocio que han sido declarados como 'protected'). En la pestaa 'Project Explorer' haz click con el botn derecho en la carpeta 'ejbModule' (la carpeta por defecto que crea Eclipse en un proyecto EJB para almacenar nuestras clases) y selecciona: New > Class Introduce en el campo 'Package' el nombre del paquete donde vamos a almacenar la clase de negocio (en mi caso 'es.davidmarco.ejb.slsb') y en el campo 'Name' el nombre de la clase de negocio; para este ltimo caso es conveniente usar el nombre de la clase de tests sin el sufijo 'Test' (en mi caso 'PrimerEJB') de manera que podamos asociar visualmente en el explorador del IDE cada clase de negocio ('Xxx') con su clase de tests ('XxxTest'). Haz click en el botn 'Finish' para crear la clase de negocio y aade la lgica de negocio (comienza con la solucin mas simple posible):

package es.davidmarco.ejb.slsb; public class PrimerEJB { public String saluda(String nombre) { return null; } }

Si en este punto ejecutamos el test que hemos escrito (haciendo click con el botn derecho sobre el editor donde tenemos el cdigo del test y seleccionando 'Run As > JUnit Test') este fallar (vers una barra de color rojo que indica que al menos un tests no ha pasado correctamente). Si observas la ventana 'Failure trace' (seguimiento de fallos) de la pestaa de resultados de JUnit, vers un mensaje que, traducido a espaol, indica que se esperaba como respuesta 'Hola Usuario' pero se recibi 'null'. Debajo de este mensaje puedes ver la pila de llamadas que ha generado el error, en nuestro caso ha sido la funcin esttica AssertEquals de JUnit. Volvamos al editor donde tenemos la clase de negocio y arreglemos el cdigo que est fallando:

package es.davidmarco.ejb.slsb; public class PrimerEJB { public String saluda(String nombre) { return "Hola usuario"; } }

Si ahora ejecutamos el test, veremos en la pestaa de JUnit que la barra es ahora de color verde, lo cual indica que todos los tests se han ejecutado sin fallos (la ventana 'Failure Trace' esta ahora vaca, evidentemente). Ahora decidimos que, cuando un cliente pase un argumento de tipo null a nuestra funcin, esta deber devolver un saludo por defecto. Renombremos el nombre del primer test que hemos escrito y escribamos un segundo test que pruebe esta nueva condicin (desde ahora y hasta el final de esta seccin omitir en ambas clases las sentencias package e import por claridad):

public class PrimerEJBTest { @Test public void testSaludaConNombre() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola usuario", ejb.saluda("usuario")); } @Test public void testSaludaConNull() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola desconocido", ejb.saluda(null)); } }

Como se dijo previamente, mediante TDD estamos dejando claras las intenciones de nuestro cdigo antes incluso de escribirlo, como se puede ver en el segundo tests. En l, esperamos recibir como respuesta la cadena de texto 'Hola desconocido' cuando invoquemos el mtodo saluda() con un argumento de tipo null. Y mientras tanto, el primer test (que hemos renombrado para darle ms claridad y expresividad a nuestros tests) debe seguir pasando, por supuesto. Ejecutamos los tests ('Run As > JUnit Test') y el nuevo test que hemos escrito falla (podemos ver en la ventana a la izquierda de la pestaa de JUnit el/los test/s que ha/n fallado marcados con una cruz blanca sobre fondo azul). Volvamos al editor donde estamos escribiendo la lgica de negocio e

4 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

implementemos la nueva funcionalidad:

public class PrimerEJB { public String saluda(String nombre) { if(nombre == null) { return "Hola desconocido"; } return "Hola usuario"; } }

Ahora ambos tests pasan. Para terminar, que ocurrira si en lugar de la cadena de texto 'usuario' pasamos al mtodo saluda() una cadena de texto distinta?. Aadamos un test que pruebe esta condicin:

public class PrimerEJBTest { @Test public void testSaludaConNombre() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola usuario", ejb.saluda("usuario")); } @Test public void testSaludaConOtroNombre() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola Pedro", ejb.saluda("Pedro")); } @Test public void testSaludaConNull() { PrimerEJB ejb = new PrimerEJB(); assertEquals("Hola desconocido", ejb.saluda(null)); } }

Este ltimo test demuestra, al ejecutarse y fallar, que nuestra lgica de negocio contiene un bug: siempre que invocamos el mtodo saluda() con un parmetro de tipo String (diferente de null) obtenemos la cadena de texto 'Hola usuario', ignorando as el parametro que le hemos pasado. He aqu otra ventaja ms que surje del uso de TDD: descubrir bugs lo antes posible. Cuanto ms tiempo tardemos en descubrir un bug, ms dificil nos resultar encontrarlo y solucionarlo. Vamos a resolver este ltimo error en nuestra lgica de negocio:

public class PrimerEJB { public String saluda(String nombre) { if(nombre == null) { return "Hola desconocido"; } return "Hola " + nombre; } }

Ahora todos los tests pasan. Aunque an nos quedara la tarea de refactorizar los tres mtodos de tests (hay cdigo redundante en todos ellos) y tal vez aadir algn test ms (o eliminar...), vamos a dejar las cosas aqu. TDD es un tema demasiado amplio y complejo que est fuera del propsito de este tutorial. Aunque este ejemplo ha sido extremadamente simple/tonto/llamalo-como-quieras, nos ha servido para demostrar lo facil que es disear un componente EJB paso a paso y libre de errores. Nadie quiere software que falle, y por tanto debes tomarte la tarea de testear el cdigo que escribes muy en serio. Test-Driven Development es una manera muy sencilla y divertida de disear software de calidad.

1.7 DESPLEGANDO NUESTRO PRIMER EJB Hasta ahora hemos tratado la clase PrimerEJB como si fuera un componente EJB. Pero lo cierto es que no es as (en otras palabras, te he mentido, aunque espero que puedas perdonarme...). Para que nuestro POJO sea reconocido por nuestro contenedor como un componente EJB verdadero tenemos que decirle que lo es:

package es.davidmarco.ejb.slsb; import javax.ejb.Stateless; @Stateless public class PrimerEJB { // ... }

5 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

La anotacin @Stateless define nuestro POJO como un Session Bean de tipo Stateless y una vez desplegado en un contenedor EJB, este lo reconocer como un componente EJB que podremos usar. As de simple!. Sin embargo, debemos aadir una segunda anotacin a nuestro (ahora si) componente EJB:

package es.davidmarco.ejb.slsb; import javax.ejb.Remote; import javax.ejb.Stateless; @Remote @Stateless public class PrimerEJB { public String saluda(String nombre) { if(nombre == null) { return "Hola desconocido"; } return "Hola " + nombre; } }

La anotacin @Remote permite a nuestro EJB ser invocado remotamente (esto es, desde fuera del contenedor). Si omitimos esta anotacin, el EJB sera considerado como 'Local' (concepto que veremos en el prximo artculo) y solo podra ser invocado por otros componentes ejecutandose dentro del mismo contenedor. Nosotros la hemos incluido pues en la prxima seccin vamos a escribir un cliente Java externo al contenedor que solicitar a este el componente que estamos diseado. De manera adicional, todos los componentes que sean de tipo remoto (como este) deben extender una interface (o de lo contrario se producir un error durante el despliegue):

package es.davidmarco.ejb.slsb; public interface MiInterfaceEJB { public String saluda(String nombre); }

Por ltimo modificamos nuestro EJB para que implemente la interface y el despliegue sea correcto:

@Remote @Stateless public class PrimerEJB implements MiInterfaceEJB { // ... }

La necesidad de una interface para componentes de tipo remoto, aunque que a priori pueda parecer una restriccin (o una limitacin), es necesaria para que el contenedor pueda construir la vista/proxy que ser enviada a los clientes remotos (externos al contenedor) por motivos que no vienen al caso. Adems, se considera una buena prctica que nuestras clases y mtodos de negocio se construyan sobre interfaces: de esta manera los clientes que usan nuestro cdigo trabajan con la interface, ignorando la implementacin concreta. De esta manera podemos cambiar dicha implementacin en el futuro sin romper el cdigo de nuestros clientes. Ahora ya podemos desplegar nuestra primera aplicacin EJB en el contenedor. En la pestaa 'Project Explorer' haz click con el botn derecho sobre el nombre del proyecto, y selecciona: Run As > Run on Server Durante el primer despliegue nos aparecer una ventana donde podemos seleccionar el servidor donde deseamos realizar el despliegue (aparecer por defecto el que definimos al crear el proyecto). Seleccionamos la casilla 'Always use this server when running this project' (Usar siempre este servidor cuando se ejecute este proyecto) y hacemos click en el botn 'Finish'. La pestaa 'Console' se volver activa y en ella veremos multitud de informacin relativa al proceso de arranque del servidor (puesto que no estaba arrancado). Tras unos momentos (30-40 segundos en mi equipo) el contenedor se habra levantado, y con l nuestra aplicacin EJB. Entre los ltimos mensajes de arranque del servidor puedes ver los siguientes: PrimerEJB/remote - EJB3.x Default Remote Business Interface PrimerEJB/remote-es.davidmarco.ejb.slsb.InterfaceEJB - EJB3.x Remote Business Interface Esas dos lineas nos indican dos referencia JNDI vlidas al componente EJB que hemos desplegado, y las necesitaremos cuando escribamos el cliente para que el contenedor nos devuelva el objeto correcto. Antes de finalizar esta seccin, veamos un ltimo asunto relativo al despliegue. Una vez que ya tenemos desplegada nuestra aplicacin en JBoss, si realizamos un cambio en nuestra lgica de negocio y deseamos volver a desplegar la aplicacin en el contenedor, debemos hacerlo desde la pestaa 'Servers' de Eclipse (y no desde la pestaa 'Project Explorer' como hicimos la primera vez que desplegamos la aplicacin). Para ello, primero abrimos

6 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

la pestaa 'Servers' si no es visible en el Workbench de Eclipse: Window > Show Views > Servers Si miramos a la recin abierta pestaa 'Servers' veremos la instancia de JBoss asociada a nuestro proyecto, y junto a ella una flecha. Pinchamos en esta flecha para expandir el servidor y veremos nuestro proyecto EJB. Hacemos click con el botn derecho sobre el nombre del proyecto y seleccionamos 'Full Publish'. En unos segundos nuestro proyecto estar re-desplegado (puedes ver el proceso en la pestaa 'Console'). Por otro lado, cuando iniciemos el IDE y queramos acceder a una aplicacin desplegada con anterioridad (por ejemplo desde un cliente como el que vamos a construir en la prxima seccin) debemos iniciar primero el servidor, evidentemente. Para ello, haz click con el botn derecho sobre el nombre del servidor en la pestaa 'Servers' y selecciona 'Start'.

1.8 EL CLIENTE JAVA Ahora es el momento de escribir el cliente Java, el cual va a hacer una solicitud al contenedor mediante JNDI para obtener el Stateless Session Bean que hemos creado en la seccin 1.6 y desplegado en la seccin 1.7. Con esto veremos como el contenedor gestiona todo el ciclo de vida de una aplicacin EJB as como de sus componentes, mientras los clientes solo tienen que preocuparse de solicitar el componente que necesiten y usarlo. Lo primero es crear un nuevo proyecto Java: File > New > Other Seleccionamos 'Java Project', hacemos click en 'Next', le damos un nombre al proyecto y hacemos click en 'Finish'. En la pestaa 'Project Explorer' expandimos el proyecto pinchando en la flecha que aparece a la izquierda de su nombre y en la carpeta 'src' creamos un nuevo paquete (muy recomendado) haciendo click con el botn derecho y seleccionando: New > Package Le damos un nombre al paquete (en mi caso 'es.davidmarco.ejb.cliente') y hacemos click en 'Finish'. Volvemos a hacer click con el botn derecho sobre el paquete recin creado y seleccionamos: New > Class En la ventana que nos aparecer le damos un nombre a la clase (en mi caso 'Cliente') y marcamos la casilla 'public static void main(String[] args)' para que nos cree un mtodo main() automticamente, y hacemos click en el botn 'Finish'. Antes de mostrar el cdigo del cliente es preciso mencionar que para ejecutarlo se necesitan ciertas librerias que, por motivos de simplicidad, vamos a obtener del primer proyecto (la aplicacin EJB). Para ello, en la pestaa 'Project Explorer' haz click con el botn derecho sobre el nombre del proyecto que hace de cliente y selecciona: Build Path > Configure Build Path En la ventana que se abrir seleccionamos la pestaa 'Projects', hacemos click en el botn 'Add', y marcamos la casilla correspondiente al proyecto donde est la aplicacin EJB que hemos desplegado (y que, repito, contiene todas las librerias que necesita el cliente). Para finalizar, hacemos click en el botn 'OK', y de nuevo hacemos click en el botn 'OK'. El cdigo del cliente es el siguiente:

package es.davidmarco.ejb.cliente; import import import import import java.util.Properties; javax.naming.Context; javax.naming.InitialContext; javax.naming.NamingException; es.davidmarco.ejb.slsb.MiInterfaceEJB;

public class Cliente { private static final String JNDI_PRIMER_EJB = "PrimerEJB/remote"; public static void main(String[] args) throws NamingException { Properties properties = new Properties(); properties.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); properties.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces"); properties.put("java.naming.provider.url", "jnp://localhost:1099"); Context context = new InitialContext(properties); MiInterfaceEJB bean = (MiInterfaceEJB) context.lookup(JNDI_PRIMER_EJB); String respuesta = bean.saluda("Cliente Java"); System.out.println(respuesta); } }

7 de 8

08/04/2013 10:05

davidmarco.es

http://www.davidmarco.es/blog/entrada.php?id=239

El cliente contiene una constante llamada JNDI_PRIMER_EJB a la que le hemos dado el valor de la referencia JNDI a nuestro componente (recuerda que este valor nos los dio el contenedor cuando despleg la aplicacin, como vimos al final de la seccin 1.7). Dentro del mtodo main() creamos un objeto de propiedades, introducimos los valores necesarios para acceder al contexto del contenedor EJB, y creamos dicho contexto mediante un objeto InitialContext y el objeto de propiedades que acabamos de crear y configurar. A continuacin viene lo realmente interesante: no obtenemos un objeto de tipo InterfaceEJB mediante el constructor new (como haramos en una aplicacin Java normal), si no que se lo solicitamos al contenedor EJB a traves del mtodo lookup() del contexto que acabamos de crear. A este mtodo le hemos pasado el nombre de la referencia JNDI del componente que queremos obtener. Recuerda que cuando solicitamos al contenedor un componente de tipo Session Bean (ya sea Stateless, Stateful, o Singleton) lo que obtenemos no es una instancia del componente EJB (en nuestro caso PrimerEJB), si no una vista (un objeto proxy) que sabe como alcanzar el objeto real dentro del contenedor. Una vez que tenemos la vista podemos ejecutar cualquiera de los mtodos que definimos en su interface asociada (MiInterfaceEJB). Para ejecutar el cliente nada tan sencillo como hacer click con el botn derecho sobre el editor donde lo tenemos y seleccionar: Run As > Java Application En la pestaa 'Console' aparecera el resultado de la ejecucin del cliente. A modo de experimento puedes cambiar la invocacin al mtodo saluda(), pasarle un valor null en lugar de una cadena de texto, volver a ejecutar el cliente, y ver la respuesta del componente EJB.

1.9 RESUMEN Este primer artculo del tutorial de introduccin a EJB 3.1 ha sido muy fructfero. En el hemos visto de manera superficial los conceptos bsicos de la especificacin EJB, una breve introduccin al contenedor EJB, los tipos de componentes que podemos producir, un sencillo ejemplo de Test-Driven Development + EJB, la forma de desplegar dicho ejemplo en un contenedor compatible con EJB, y como acceder al componente (a travs del contenedor) desde un cliente Java. En el prximo artculo veremos en profundidad dos de los tres tipos de componentes de tipo Session Bean: Stateless Session Beans y Stateful Session Beans. Hasta entonces, felices despliegues!.

Volver al blog

8 de 8

08/04/2013 10:05

Vous aimerez peut-être aussi