Enterprise Java Beans Tecnología Enterprise Java Beans La especificación de Enterprise JavaBeans, define una arquitectura para el desarrollo y estructuración de aplicaciones de procesamiento de transacciones, basados en objetos distribuidos, y componentes de software del lado del servidor. Estos componentes, son llamados enterprise beans, son objetos distribuidos que se encuentran en Enterprise JavaBeans Containers y proveen servicios remotos a clientes distribuidos a través de la red. Especificaciones La especificación exige un modelo de programación, constituido por convenciones o protocolos y un conjunto de clases e interfaces sobre las cuales de apoya el EJB API. El modelo de programación de EJB provee a los desarrolladores y proveedores de beans, un conjunto de contratos que definen un estándar común para el desarrollo. El principal logro de estos contratos es asegurar la portabilidad entre distintos proveedores y así soportar un gran conjunto de funcionalidades. El Contenedor de Java Beans Enterprise Java Beans son componentes que se ejecutan en un ambiente especial llamado EJB Container. El container almacena y maneja un enterprise bean de la misma forma que un Servidor Web Java almacena un servlet, o un browser HTML almacena un applet. Un enterprise bean no puede funcionar fuera de un EJB container. El EJB Container maneja cada aspecto de un enterprise bean en tiempo de ejecución incluyendo acceso remoto al bean, seguridad, persistencia, transacciones, concurrencia y acceso a los recursos. El container protege al EJB del acceso directo desde las aplicaciones clientes. Cuando una aplicación cliente invoca un método remoto en un EJB, el container primero intercepta la invocación para asegurar la persistencia, transacciones y seguridad que son aplicadas a apropiadamente a cada una de las operaciones que el cliente desempeña en el bean. El container maneja estos aspectos automáticamente para el bean, así el desarrollador no tiene que preocuparse por la implementación de los mismos. Los containers pueden manejar numerosos beans en la misma forma que un servidor web puede manejar varios servlets. Para reducir el consumo de memoria, procesamiento y los recursos del container, este maneja los bean por ciclos de vida. Cuando un bean no esta en uso, el container lo coloca en una pila para ser rehusado por otro cliente, o posiblemente lo saca de memoria y solo lo trae de nuevo cuando es necesario. Como las aplicaciones clientes no tienen acceso directo a los bean, estas están completamente ajenas a las actividades de manejos de recursos. Un bean que no esta en uso, por ejemplo, es sacado de memoria en el servidor, mientras que su referencia remota permanece intacta en el cliente. Cuando el cliente invoca un método sobre su referencia remota, el container reencarna el bean para atender la petición. El cliente, es ignorante de todo el proceso. La siguiente figura, resume el comportamiento del EJB Container Enterprise Beans Un EJB esta compuesto de 4 partes (con la excepción de "Messaging EJB's") las cuales son: o "Enterprise Bean Class" o "Home Interface" o "Remote Interface" o "Deployment Descriptor" Enterprise Bean Class Esta clase es el componente medular de un EJB, en esta clase se encuentran definidas todas los funciones utilizadas por un EJB, ya sean procedimientos rutinarios (operaciones matemáticas) o con lógica hacia bases de datos (con JDBC). En esta clase reside todo el código fuente o funcional que realiza operaciones en Java, desde la activación del EJB hasta su destrucción incluyendo las funciones de negocios para el que éste fue diseñado. Home Interface Esta interfase solo define un "esqueleto" para funciones utilizadas en el Enterprise Bean Class. Los métodos que deben ser declarados en un Home Interface son aquellos que representan el ciclo de vida del componente (creaciónactivación) algunas son: create, destroy, find. Cuando un cliente desea interactuar con un EJB éste no se comunica directamente con el Enterprise Bean Class, sino con el Home Interface del EJB en cuestión. Remote Interface Esta interfase contiene las declaraciones para métodos de negocios definidos en el Enterprise Bean Class. Deployment Descriptor Un Deployment Descriptor es un archivo en XML que cumple varias funciones. La primera es parametrizar el código Java del "Enterprise Bean Class", esto es, definir parámetros que varían dependiendo del ambiente; por lo general todo EJB contiene algún tipo de lógica que dependerá del ambiente de ejecución como: nombres de bases de datos, servidores de paginas, usuarios privilegiados, etc... y es a través del Deployment Descriptor que estos parámetros pueden ser modificados sin la necesidad de entrar a todo el código fuente, inclusive para aquellos EJB adquiridos de 3eros los cuales no distribuyen su código fuente es la única manera de personalizar este tipo de parámetros. Además de lo anterior, el Deployment Descriptor también indica al EJB Container: el tipo de EJB ("Session, Entity, Messaging"), el esquema de seguridad que posee el EJB, en caso de ser un "Container Managed Entity EJB" las funciones para las que se generará lógica, y otras funcionalidades más. Tipos de Beans Beans Entidad Un bean entidad representa un objeto de negocios en un mecanismo de almacenamiento persistente. El mecanismo de almacenamiento persistente, generalmente, se refiere a una base de datos relacional. Típicamente, cada bean entidad implica una tabla en una base de datos relacional, y cada instancia de un bean corresponde a una fila de la misma. Existen dos tipos de bean entidad: o BMP: Bean-Managed Persistence o CMP: Container-Managed Persistence BMP Este tipo de bean requiere que la lógica necesaria para accesar a la base de datos sea definida manualmente, por lo general esta lógica se encuentra en JDBC y define: como y cuando debe ser accesada|actualizada|guardada la información entre el EJB y la base de datos CMP El temimo container-managed persistence significa que el EJB Container maneja todos los accesos a la base de datos que requiera el bean entidad. El código del bean no contiene ningún acceso a la base de datos. Como resultado el código del bean es ajeno a una base de datos especifica, debido a esta flexibilidad, aun si se necesita re-estructurar el mismo bean entidad en un servidor que use una base de datos diferente, no se necesitara modificar o recompilar el código del bean. Aparentemente un BMP no tiene mucha razón de ser, sin embargo, hay casos donde es empleada lógica de acceso sumamente compleja la cual no es posible generar a través del EJB Container, es por esto que los BMP permanecerán en existencia a pesar de las facilidades ofrecidas por los CMP. Beans Sesión Los beans sesión representan un conjunto de procesos o tareas, los cuales son desempeñadas para la aplicación cliente. No representan datos como los bean entidad. Los beans sesión, pueden usar otros beans para completar las tareas o acceder directamente a la base de datos. Como su nombre sugiere, un bean sesión es similar a una sesión interactive. Un bean sesión, no es compartido solo tiene un solo cliente, de la misma forma que una sesión interactiva solo tiene un solo usuario. Una bean sesión no es persistente. Cuando un cliente termina, el bean sesión finaliza y no esta mas asociado con el cliente. Existen dos tipos de beans sesión: Stateless Session Beans Este tipo de EJB como su nombre lo indica no mantiene estado("Stateless") en el "EJB Container", estos EJB's son utilizados para realizar tareas rutinarias que no requieren identificar o rastrear al cliente, algunos EJB's de este tipo son: operaciones matemáticas complejas, búsquedas generales, etc. Stateful Session Beans A diferencia de "Stateless (Session) EJB's" este tipo de EJB's permiten mantener la sesión del cliente en el "EJB Container", de esta manera el cliente puede trabajar con cierto juego de datos especifico administrado por el "EJB Container", la aplicación ideal para este tipo de EJB es un componente de compra ("Shopping Cart") el cual puede identificar artículos e información personal del cliente a través de un lapso de tiempo extenso ("Session"). Message-Driven A muy grandes rasgos un sistema "Messaging" ofrece el funcionamiento de intermediario para recibir y publicar mensajes, una de las ventajas de un "Messaging System" es que opera en forma asíncrona o non-bloqueante. Los mensajes pueden ser enviados por cualquier aplicación cliente, otro enterprise bean, un componente web, u otra aplicación basada en JMS (Java Message Servicie) Asíncrono o no-bloqueante implica que un cliente (emisor) pueda publicar un mensaje sin la necesidad que el receptor se encuentre activo, esencialmente el "Messaging System" funciona como un agente ("broker") para facilitar el intercambio de mensajes. Las aplicaciones clásicas para un "Messaging System" son aquellas utilizadas por sistemas financieros, en donde la perdida de mensajes es intolerable o ampliamente distribuida. Cuando ocurre una transacción financiera generalmente esta atraviesa por un "Messaging System", lo cual garantiza que aunque el consumidor final (receptor) este desactivado el cliente(emisor) pueda continuar con sus acciones sin la necesidad de esperar confirmación, a esto último se le llama "non-blocking". Otra aplicación financiera que utiliza "messaging" son los denominados "tickers financieros" donde constantemente aparecen los valores de acciones, en este tipo de sistema existe un cliente(emisor) que publica el mensaje ("valor de acciones") al "Messaging system", y cientos o miles de consumidores (receptores) "tickers financieros" toman este mensaje del "messaging system" para ser desplegado en pantalla. Cuando usar beans entidad: •El bean representa una entidad de negocios no un procedimiento. Por ejemplo, CreditCardEJB puede ser un bean entidad, pero CreditCardVerifierEJB debe ser un bean ser un bean sesión. • El estado del bean debe ser persistente. Cuando usar beans sesión: En general, se deben usar beans sesión cuando: • Solo un cliente tiene acceso a la instancia del bean. • El estado del bean es no persistente, solo existe por un corto periodo de tiempo. Stateful beans son apropiados cuando •El estado del bean representa la interacción entre el bean y un cliente en especifico. • El bean necesita mantener información del cliente a lo largo de las invocaciones a los métodos. • El bean es un mediador entre el cliente y otros componentes de la aplicación. • El bean maneja el flujo de trabajo de muchos enterprise beans. Es recomendable usar beans sesión stateless cuando: • El estado del bean no tiene datos de un cliente especifico • El bean desempeña tareas genéricas para todos los clientes. • El bean trae de la base de datos un conjunto de datos solo-lectura que son usados con frecuencia por sus clientes, por ejemplo filas de la tabla que representan los productos en rebajas este mes. Creación de un Enterprise JavaBean en el Servidor: Una aplicación cliente contacta al servidor y le pide que genere un EJB para que procese datos en su nombre. El servidor responde creando un Objeto en él (la instancia del componente del EJB), y devuelve un objeto proxy (el Objeto EJB) cuya interfaz es la misma que la del componente del EJB y su implementación invoca métodos remotos a nombre del cliente. El cliente luego utiliza el objeto como si fuese un objeto local, sin saber que realmente el objeto remoto es el que esta haciendo todo el trabajo. La aplicación cliente al que realmente contacta es al conteiner del servidor y le pide que genere un objeto en particular, el conteiner responde con el Objeto EJB que puede ser utilizado para manipular el nuevo componente EJB recién generado. Como ya se explico anteriormente el ciclo de vida de los beans del servidor es responsabilidad del conteiner. Cada clase del componente del EJB tiene un home interface, que define los métodos para crear, inicializar, destruir y (en caso de los entity beans) buscar instancias de EJB en el servidor. Los home interface define uno a mas métodos create(), que devuelven valores de remote interface del EJB. Como se explico anteriormente el remoto interface consiste de los métodos de negocios que provee el EJB. Cuando un cliente quiere crear un bean en el servidor, este utiliza el JNDI (java naming and director interface) para localizar el home interface de la clase de bean que él desea. El JNDI es una extensión estándar del core de java que provee un servicio global para cualquier ambiente de java, permitiendo que aplicaciones en java localicen y utilicen recursos por nombre, obteniendo información acerca de esos recursos, entre otras cosas. Una vez que el cliente tiene el home interface de la clase del EJB que quiere generar, se llama a uno de los métodos create() en el home interface para crear el objeto en el servidor. El objeto del home interface del lado del cliente hace una llamada remota al conteiner del EJB, quien luego genera el componente EJB y devuelve el objeto EJB al cliente. Luego el cliente puede llamar los métodos del objeto EJB, estas llamadas son enviadas al conteiner. El conteiner difiere la implementación de los métodos de las llamadas invocadas a los componentes del EJB. Más de los EJB Container Como se menciono anteriormente, los conteiner aíslan a los Enterprise beans de acceso directo por parte de las aplicaciones de los clientes. Cuando una aplicación invoca un método remoto en un Enterprise bean, él intercepta la invocación para asegurar la persistencia, transacción, y la seguridad es aplicada adecuadamente a cada operación que el cliente realice en el bean. De esta forma el conteiner maneja automáticamente por los beans la seguridad, transacciones y la persistencia, así los desarrolladores de beans no se tienen que preocupar por escribir este tipo de lógica en los códigos de los beans. Los desarrolladores de Enterprise beans se pueden enfocar en encapsular las reglas del negocios, mientras los conteiner se encargan de todo lo demás. Los conteiner manejan varios bean simultáneamente de la misma manera como los servidores web de java manejan varios servlets. Para reducir el consumo y procesamiento de memoria, los conteiner agrupan los recursos y manejan el ciclo de vida de todos los beans muy cuidadosamente. Cuando un bean no esta siendo utilizado, el conteiner lo pondrá en un lista para que pueda ser reutilizado por otro cliente, o posiblemente lo expulse de la memoria y solo lo trae de vuelta cuando sea necesario. Debido a que las aplicaciones de los clientes no tienen acceso directo a los bean, las aplicaciones de los clientes están completamente desprevenidas de las actividades de dirección que realiza los conteiner. Por ejemplo si un bean no esta siendo utilizado este puede ser expulsado de la memoria del servidor, mientras que su referencia remota en el cliente quedan intactas. Cuado el cliente invoca un método en la referencia remota, el conteiner simplemente reencarna al bean para servir la solicitud. La aplicación del cliente desconoce totalmente todo ese proceso. Los Enterprise beans dependen de los conteiner para todas las cosas que necesiten. Si un Enterprise bean necesita acceder a una conexión JDBC o a otro Enterprise bean, lo hace a través del conteiner, si un Enterprise bean necesita acceder la identidad de su llamador, obtener una referencia a sí mismo o acceder a sus propiedades, lo hace a través del conteiner. Los Enterprise bean interactúan con él por medio de alguno de los siguientes tres mecanismos: metdos callbacks, el EJBContext interface, o el JNDI. Callbacks: Todos los bean implementan un subtipo de interfaz EnterpriseBean que define varios métodos, llamados los métodos callback. Cada método callback avisa al bean sobre diferentes eventos en su ciclo de vida y el conteiner invocara estos métodos para notificar al bean cuando esta a punto de activar el bean, persistir su estado a la bases de datos, terminar una transacción, mover el bean de la memoria etc. Los métodos callback permiten que los beans tengan chance de realizar algunas actividades inmediatamente antes de un determinado evento ocurra. EJBContext: Cada bean obtiene un objeto EJBContext, el cual es una referencia directa al conteiner. La interfaz EJBContext provee de métodos para que el bean pueda solicitar información acerca de su ambiente como la identidad de su cliente, el estado de su transacción, o para obtener una referencia remota a él mismo. JNDI: Es una extensión estándar de la plataforma java para acceder a un naming system como LDAP, NetWare, sistema de archivos, etc. Cada bean tiene acceso a un sistema de nombramiento especial llamado Environment Naming Context(ENC). El ENC es manejado por el conteiner y accedido por los bean usando JNDI. El JNDI ENC permite a los bean acceder a recursos como conexiones de JDBC, otros Enterprise beans, y propiedades especificas de esos beans. Enterprise beans como objetos distribuidos. Las interfases remotas y home son tipos de interfases remotas de RMI de Java. La interfaz java.rmi.Remote es utilizada por objetos remotos para representar los bean en una dirección de espacio diferente ya sea en un procesador o maquina diferente. Un Enterprise bean es un objeto distribuido, con lo que quiere decir que la clase bean es inicializada y vive en el conteiner y puede ser accedida por aplicaciones que vivan en otro espacio de dirección. Para hacer que un objeto que esta instanciado en una dirección de espacio este disponible en otra requiere de un pequeño truco que envuelven network Socket. Para hacer que el truco funciones se envuelve la instancia en un objeto especial llamado esqueleto el cual contiene una conexión network con otro objeto especial llamado stub. Los stub implementan la interfaz remota por lo que aparentan ser un objeto de negocios, pero los stub no contienes lógica de negocios, contiene un conexión network socket al esqueleto. Cada vez que se invoca un método de negocio en la interfaz remota del stub, el stub envía un mensaje de red al esqueleto informándole sobre que método esta siendo invocado. Cuando el esqueleto recibe este mensaje identifica el método invocado y sus argumentos, y luego invoca el correspondiente método en la instancia actual. La instancia ejecuta el método y devuelve su resultado al esqueleto, el cual lo envía de regreso al stub. El stub devuelve el resultado a la aplicación que invoco el método de interfaz remota. Desde la perspectiva de la aplicación que invoca el método pareciera que el stub es el que hace todo el trabajo. Cuando en realidad el stub es como un objeto de red mudo que envía lo solicitado a través d la red hacia el esqueleto, el cual envía el mensaje a la instancia que es la que realmente hace todo el trabajo, los stubs y los esqueletos solo pasan la identidad del método y sus argumentos a través de la red. En EJB los esqueletos son para las interfaces remotas y home están implementados por el container y no por las clase bean. Esto es para asegurara que todo método invocado por las aplicaciones clientes son primeramente manejados por el container y luego son delegados a la respectiva instancia del bean. Los protocolos de objetos distribuidos definen el formato de los mensajes de red enviados entre los espacios de direcciones. Los protocolos de objetos distribuidos se pueden poner bastante complicados, pero afortunadamente uno no ve nada de esto por que es manejado automáticamente. La mayoría de los servidores de EJB soportan o el Java Remote Meted Protocol (JRMP) o el protocolo de CORBA Internet Inter.-ORB Protocol (IIOP). Los programadores de los bean y de las aplicaciones solo ven las clases bean y su interfaz remota, los detalles de la comunicación por la red es escondida. Con respeto al API del EJB, los programadores no les importa si el servidor EJB utiliza JRMP o IIAP (el API es el mismo). Las especificaciones del EJB requieren que se utilicen una versión especializada del API del RMI Java, cuando se esta trabajando con un bean remotamente. RMI de Java es un API para acceder objetos distribuidos. Desventajas de EJB ("Enterprise Java Beans") Tiempo de Desarrollo El desarrollar un Sistema con EJB's es sumamente complejo, aunque para ciertas empresas puede presentar una solución ideal, debido a la complejidad-tiempo de ( traduciéndose en costo) para muchas corporaciones EJB's resultan una solución sobrada , denominada en Ingles: "overkill". Conocimiento exhausto de Java EJB's es uno de los principales componentes de J2EE por esta razón también depende fuertemente de otras partes de J2EE: Como RMI, JNDI y JDBC. EJEMPLO A continuación un ejemplo de como una customer bean puede ser accedido desde una aplicación de cliente. En este ejemplo la interfaz home es del tipo CustomerHome la interfaz remota es del tipo Customer. CustomerHome home = // ... obtain a reference that // implements the home interface. // Use the home interface to create a // new instance of the Customer bean. Customer customer = home.create(customerID); // using a business method on the Customer. customer.setName(someName); La interfaz remota define los métodos de negocios del bean, los métodos que son específicos de los conceptos de negocios al cual representa. A continuación esta una definición de una interfaz remota para el bean Customer. import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Customer extends EJBObject { public Name getName() throws RemoteException; public void setName(Name name) throws RemoteException; public Address getAddress() throws RemoteException; public void setAddress(Address address) throws RemoteException; } la interfaz remota define métodos para acceder y modificar información acerca de los conceptos de negocios. Esto es típico de un tipo de bean llamado entity bean, que representa un objeto de negocios persistente. Objetos de negocios que son almacenados en las bases de datos. Los entity beans representan la información de negocios en la base de datos y añaden comportamientos específicos a esa información. métodos de negocios: Los métodos de negocios también pueden representar tareas que el bean puede realizar. A pesar que los entity beans puede tener a menudo métodos orientados a tareas, este tipo de métodos son típicos de los sesión bean. Session bean no representan información como los entity beans. Ellos representan procesamiento de negocios o agentes que realizan servicios, como hacer una reservacion a un hotel. A continuación esta una definición de la interfaz remota para el bean HotelClerk, el cual es un bean del tipo session. import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface HotelClerk extends EJBObject { public void reserveRoom(Customer cust, RoomInfo ri,Date from, Date to) throws RemoteException; public RoomInfo availableRooms( Location loc, Date from, Date to) throws RemoteException; } Los métodos de negocios definidos en la interfaz remota HotelClerk representan procesamiento en vez de simples métodos de acceso a información. El bean HotelClerk actua como un agente en el sentido que realiza tareas en nombre del usuario, pero no es el mismo persistente en la base de datos. No necesitamos información acerca del hotelclerk, se necesita que el hotel clerk realice tareas para nosotros. Este es el comportamiento típico de los session bean. Mientras se va construyendo una aplicación de EJB se van a ir creando muchos beans, cada uno simbolizando diferentes conceptos de negocios. Cada concepto de negocio se manifestara como un entity bean o como un session bean. Uno decidirá que tipo de bean se convertirá un concepto de negocios basándose en como se desee utilizar. Entity bean: Para cada interfaz remota existe una clase de implementación. Un objeto de negocios que realmente implementa los métodos de negocios definidos en la interfaz remota. Esta es como ya hemos dicho la clase bean. A continuación una definición parcial del customer bean class. import javax.ejb.EntityBean; public class CustomerBean implements EntityBean { Address myAddress; Name myName; CreditCard myCreditCard; public Name getName() { return myName; } public void setName(Name name) { myName = name; } public Address getAddress() { return myAddress; } public void setAddress(Address address) { myAddress = address; } ...} CustmerBean es una clase de implementación, ella contiene información y provee de métodos de acceso y otros métodos de negocio. Como los entity bean, el CustomerBean provee un objeto para ver la infamación del customer. En vez de escribir accesos lógicos a la bases de datos en una aplicación , la aplicación puede simplemente utilizar la interfaz remota del CustomerBean para acceder a la información del customer. Session bean: El HotelClerk es un session bean , el cual es muy similar en muchos aspectos a un entity bean. Session bean representa un conjunto de procesamiento de tareas, las cuales son ejecutadas en nombre de la aplicación del cliente. Los bean de session pueden utilizar otros beans para que realicen tareas o para que accedan directamente a la base de datos. A continuación un ejemplo que muestra los dos casos: import javax.ejb.SessionBean; public class HotelClerkBean implements SessionBean { public void reserveRoom( Customer cust, RoomInfo ri, Date from, Date to) { CreditCard card = cust.getCreditCard(); RoomHome roomHome = // ... get home reference Room room = roomHome.findByPrimaryKey(ri.getID()); double amount = room.getPrice(from,to); CreditServiceHome creditHome = // ... get home reference CreditService creditAgent = creditHome.create(); creditAgent.verify(card, amount); ReservationHome resHome = // ... get home reference Reservation reservation = resHome.create(cust,room,from,to); } public RoomInfo[] availableRooms( Location loc,Date from, Date to) { // Make an SQL call to find //available rooms Connection con = // ... get database //connection Statement stmt = con.createStatement(); ResultSet results = stmt.executeQuery("SELECT ..."); ... return roomInfoArray; } } ciclo de vida de los métodos: adicionalmente a los remote interface todos los bean tienen un home interface que provee los métodos del ciclo de vida para crear, destruir y localizar beans. Estos comportamiento del ciclo de vida están separados de la interfaz remota por que ellos representan comportamiento que no es especifico de una única instancia de bean. A continuación una definición del home interface de l customer bean. import import import import javax.ejb.EJBHome; javax.ejb.CreateException; javax.ejb.FinderException; java.rmi.RemoteException; public interface CustomerHome extends EJBHome { public Customer create(Integer customerNumber) throws RemoteException, CreateException; public Customer findByPrimaryKey(Integer customerNumber) throws RemoteException, FinderException; public Enumeration findByZipCode(int zipCode) throws RemoteException, FinderException; } El método create() es utilizado para crear una nueva entidad. Esto resultara en un nuevo registro en la basa de datos. Pueden haber varios métodos create() en home. Se diferencia en el tipo y número de argumentos, pero lo que devuelven debe ser del tipo remote interface. En este caso el método create devuelve una instancia de Customer. métodos utilizados para ubicar determinadas instancia de Customer bean. Devuelta a remote y home interface: Estas dos interfaces es utilizada por las aplicaciones para acceder a los EB. El home interface permite que la aplicación cree y localice el bean, mientras que el remote interface permite a la aplicación invocar los métodos de negocios de los beans CustomerHome home = // Get a reference to the //CustomerHome object Customer customer = home.create(new Integer(33)); Name name = new Name("Richard", "Wayne", "Monson-Haefel"); customer.setName(name); Enumeration enumOfCustomers = home.findByZip(55410); Customer customer2 = home.findByPrimaryKey( new Integer(33)); Name name2 = customer2.getName(); // output is "Richard Wayne //Monson-Haefel" System.out.println(name); Referencias: Enterprise JavaBeansTM(EJB) Technology Fundamentals http://developer.java.sun.com/developer/onlineTraining/EJBIntro/ Enterprise JavaBeansTM Tutorial: Building Your First Stateless Session Bean http://developer.java.sun.com/developer/onlineTraining/Beans/EJBTutorial/index.html White Papers http://java.sun.com/j2ee/white/index.html