Session Beans y Entity Beans básico

Anuncio
Session Beans y
Entity Beans
Ignacio Ramos Zapata
Departamento de Ingeniería Telemática
Universidad Carlos III de Madrid
[email protected]
Contenido
Ÿ Caso de estudio
Ÿ Gestión de recursos
– Pooling de instancias
– Activación/pasivación
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
2
1
Caso de estudio: Entity Bean
Ÿ Ejemplo entity bean: Cabin
– modela un camarote en un barco crucero
– Interfaz component: CabinRemote
– Interfaz home: CabinHomeRemote
– Clase: CabinBean
– la palabra Remote se suele añadir a los nombres
de los interfaces remotos para distinguirlos de
interfaces locales (que se introdujeron en la
especificación 2.0 de los EJB)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
3
CMP Entity Bean
Ÿ Cabin es un entity bean CMP, la persistencia
por tanto está gestionada por el contenedor
Ÿ La clase bean ha de proporcionar la
implementación de los métodos que gestionan
el ciclo de vida del bean
– Determinados por la interfaz javax.ejb.EntityBean
Ÿ Es necesario especificar en el deployment
descriptor los campos cuya persistencia va a
gestionar el container
Ÿ Dicha persistencia es independiente de la base
de datos (los hace muy portables)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
4
2
Home Interface: CabinHomeRemote
package com.titan.cabin;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.FinderException;
public interface CabinHomeRemote extends javax.ejb.EJBHome {
public CabinRemote create(Integer id)
throws CreateException, RemoteException;
public CabinRemote findByPrimaryKey(Integer pk)
throws FinderException, RemoteException;
}
Ÿ CreateException, FinderException -> excepciones que el Objeto Home lanza
2005
–
cuando no puede crear una instancia
–
cuando dada una clave, no puede encontrar la instancia del EJB
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
5
Primary Key Class
Ÿ Identifica de manera a una instancia de un
bean
Ÿ Tiene que implementar el interfaz
java.io.Serializable
Ÿ Tiene que ser una clase
– Se puede usar el tipo String
– No sirven atributos primitivos como int o float, en
su lugar hay que usar wrappers Java tales como
Double o Integer
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
6
3
Component Interface: CabinRemote
package com.titan.cabin;
import java.rmi.RemoteException;
public interface CabinRemote extends javax.ejb.EJBObject {
public
public
public
public
public
public
public
public
String getName()throws RemoteException;
void setName(String str)throws RemoteException;
int getDeckLevel()throws RemoteException;
void setDeckLevel(int level)throws RemoteException;
int getShipId()throws RemoteException;
void setShipId(int sp)throws RemoteException;
int getBedCount()throws RemoteException;
void setBedCount(int bc)throws RemoteException;
}
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
2005
7
Clase bean: CabinBean (I)
package com.titan.cabin;
import javax.ejb.EntityContext;
import javax.ejb.CreateException;
public abstract class CabinBean
implements javax.ejb.EntityBean {
public Integer ejbCreate(Integer id)
throws CreateException {
this.setId(id);
return id;
}
public void ejbPostCreate(Integer id)
throws CreateException {
}
[…]
El container extiende esta clase (abstracta) y se encarga de
proporcionar el código necesario para asegurar la persistencia
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
8
4
Clase bean: CabinBean (II)
[…]
public abstract void setId(Integer id);
public abstract Integer getId();
public abstract void setShipId(int ship);
public abstract int getShipId( );
public abstract void setName(String name);
public abstract String getName( );
public abstract void setBedCount(int count);
public abstract int getBedCount( );
public abstract void setDeckLevel(int level);
public abstract int getDeckLevel( );
[…]
El container es responsable de salvar el estado de aquellos campos
especificados en el deployment descriptor
Hay que proporcionar setters y getters como métodos abstractos (que el
container se encarga de implementar)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
9
Clase bean: CabinBean (III)
public void setEntityContext(EntityContext ctx) {
// Not implemented.
}
public void unsetEntityContext() {
// Not implemented.
}
qejbActivate/ejbPosivate
public void ejbActivate() {
asociados al proceso de
// Not implemented.
}
activación/pasivación
public void ejbPassivate() {
qejbLoad/ejbStore se
// Not implemented.
invocan cuando el EJB se
}
carga o se almacena su
public void ejbLoad() {
estado en la DB
// Not implemented.
qejbRemove se invoca
}
antes de destruir el EJB
public void ejbStore() {
// Not implemented.
}
public void ejbRemove() {
// Not implemented.
}
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
10
5
Comentarios sobre el Cabin Bean
Ÿ El método ejbCreate debe tener un método
create en el Home interface con la misma
signatura
Ÿ El Home de entity beans siempre debe definir
al menos el método findByPrimaryKey
Ÿ En entity beans con persistencia manejada
por contendor no necesitan implementarlo (lo
hace el contenedor)
Ÿ Los métodos de acceso a atributos
persistentes los implementa directamente el
contendor
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
11
Deployment descriptor CabinEJB (I)
<!DOCTYPE ejb-jar PUBLIC “...>
<ejb-jar><enterprise-beans>
<entity>
<ejb-name>CabinEJB</ejb-name>
<home>com.titan.cabin.CabinHomeRemote</home>
<remote>com.titan.cabin.CabinRemote</remote>
<ejb-class>com.titan.cabin.CabinBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.Integer</prim-key-class>
<reentrant>False</reentrant>
<abstract-schema-name>Cabin</abstract-schema-name>
-
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
12
6
Deployment descriptor CabinEJB (II)
<cmp-field><field-name>shipId</field-name></cmp-field>
<cmp-field><field-name>name</field-name></cmp-field>
<cmp-field><field-name>deckLevel</field-name></cmp-field>
<cmp-field><field-name>bedCount</field-name></cmp-field>
<cmp-field><field-name>id</field-name></cmp-field>
<primkey-field>id</primkey-field>
...
</entity>
</enterprise-beans>
<assembly-descriptor>
...
</assembly-descriptor>
</ejb-jar>
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
13
Creación de una tabla Cabin en la BD
Ÿ Con la herramienta de instalación (deployment)
Ÿ create table CABIN
(
ID int tprimary key NOT NULL,
SHIP_ID int,
BED_COUNT int,
NAME char(30),
DECK_LEVEL
INT
)
Ÿ Se utiliza para mantener la persistencia. Se suele definir
una tabla por cada clase y una columna por cada
variable
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
14
7
Mapping entre Objetos y DB Relacionales
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
15
Pool de Conexiones
Ÿ Los entity beans requieren frecuentes pero
cortas interacciones con la DB
– El acceso a los campos cuya persistencia es
gestionada por el contenedor
– No suele ser gran cantidad de información
Ÿ Usar un pool de conexiones puede mejorar el
rendimiento
– Minimiza el tiempo necesario para abrir y la
conexión con la DB
– Permite controlar el número de conexiones
abiertas
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
16
8
Cliente de CabinEJB (I)
package com.titan.clients;
import com.titan.cabin.CabinHomeRemote;
import com.titan.cabin.CabinRemote;
import
import
import
import
import
import
2005
javax.naming.InitialContext;
javax.naming.Context;
javax.naming.NamingException;
javax.rmi.PortableRemoteObject;
java.rmi.RemoteException;
java.util.Properties;
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
17
Cliente de CabinEJB (I)
// imports
public class Client1 {
public static void main(String [] args) {
try {
Context jndiContext = getInitialContext();
Object ref =
jndiContext.lookup("CabinHomeRemote");
CabinHomeRemote home = (CabinHomeRemote)
PortableRemoteObject.
narrow(ref,CabinHomeRemote.class);
if ( ref != null ) {
System.out.println("Found Cabin Home");
}
CabinRemote cabin_1=home.create(new Integer(1));
cabin_1.setName("Master Suite");
cabin_1.setDeckLevel(1);
cabin_1.setShipId(1);
cabin_1.setBedCount(3);
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
18
9
Cliente de CabinEJB (II)
Integer pk = new Integer(1);
CabinRemote cabin_2 = home.findByPrimaryKey(pk);
System.out.println(cabin_2.getName());
System.out.println(cabin_2.getDeckLevel());
System.out.println(cabin_2.getShipId());
System.out.println(cabin_2.getBedCount());
} catch (java.rmi.RemoteException re)
{re.printStackTrace();}
catch (javax.naming.NamingException ne)
{ne.printStackTrace();}
catch (javax.ejb.CreateException ce)
{ce.printStackTrace();}
catch (javax.ejb.FinderException fe)
{fe.printStackTrace();}
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
19
Cliente de CabinEJB (III)
public static Context getInitialContext()
throws javax.naming.NamingException{
Properties p = new Properties();
//... specify the JNDI Properties specific to the vendor
p.put(Context.INITIAL_CONTEXT_FACTORY,
“weblogic.jndi.WLInitialcontextFactory”);
p.put(Context.PROVIDER_URL, “t3://localhost:7001”);
return new javax.naming.InitialContext(p);
}
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
20
10
Pasos del cliente
1. Obtención de una conexión de directorio al
contenedor (mediante el servicio JNDI)
2. Hacer un lookup en ese directorio (espacio
de nombres) del bean buscado
3. Hacer un narrow de la referencia obtenida
4. Hacer un casting del resultado al objeto de
tipo HomeRemote
5. Llamar a create sobre el objeto
HomeRemote y obtener el objeto EJB
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
21
Obtención de una conexión de directorio al
contenedor (mediante el servicio JNDI)
Ÿ El objeto InitialContext recibe un objeto Properties que le indica:
– dónde está el servidor EJB
– Utility class para crear el InitialContext (dependiente del JNDI
service provider)
Ÿ El contexto inicial es como la raíz del sistema de ficheros
Ÿ JNDI permite que el cliente vea los elementos del servidor EJB
como directorios en un sistema de ficheros común
Ÿ El proceso de obtención es “parecido” a obtener una conexión al
driver de JDBC
Ÿ Los parámetros concretos del Properties dependen de la
implementación
Ÿ Lo practicaréis en la práctica (J2EE 1.3 SDK Reference
Implementation)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
22
11
Lookup en el espacio de nombres
del bean buscado
Ÿ Object ref = jndiContext.lookup("CabinHomeRemote");
Ÿ El cliente da el nombre del objeto HomeRemote
buscado (en el JNDI Global Environment)
Ÿ Veremos que cuando un bean actúa como cliente de
otro bean, busca su Home en su JNDI Environment
Naming Context (ENC) (un directorio creado al instalar el
bean):
“java:com/env” (inicial)
“java:comp/env/ejb” (para los beans a los que accede)
– También se puede acceder mediante el JNDI a propiedades y
otros recursos del contenedor, paso de parámetros en
inicialización, etc.
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
23
Narrow y casting
Ÿ CabinHomeRemote home = (CabinHomeRemote)
PortableRemoteObject.
narrow(ref,CabinHomeRemote.class);
Ÿ El narrow es una “especie” de casting para objetos
remotos (RMI sobre IIOP)
Ÿ Comprueba si se puede hacer el casting del objeto a
la clase indicada y devuelve la referencia al Object
– el protocolo se originó en CORBA, como CORBA admite
muchos lenguajes, no todos tienen un casting nativo
Ÿ No hace falta hacer narrow si la referencia devuelta
tiene directamente el tipo adecuado
– p.ej. create devuelve un objeto CabinRemote (no necesita
narrow)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
24
12
Caso de estudio: Session Bean
Ÿ Ejemplo de session bean: TravelAgent
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
25
Component Interface: TravelAgentRemote
package com.titan.travelagent;
import java.rmi.RemoteException;
import javax.ejb.FinderException;
public interface TravelAgentRemote
extends javax.ejb.EJBObject {
// String elements follow the format
// "id, name, deck level"
public String [] listCabins(int shipID, int bedCount)
throws RemoteException;
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
26
13
Home Interface: TravelAgentHomeRemote
package com.titan.travelagent;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
public interface TravelAgentHomeRemote extends
javax.ejb.EJBHome {
public TravelAgentRemote create()
throws RemoteException,
CreateException;
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
27
Clase bean: TravelAgentBean (I)
public class TravelAgentBean implements javax.ejb.SessionBean {
public void ejbCreate()throws CreateException {
// Do nothing.
}
public String [] listCabins(int shipID, int bedCount) {
try {
javax.naming.Context jndiContext = new InitialContext();
Object obj =
jndiContext.lookup("java:comp/env/ejb/CabinHomeRemote");
CabinHomeRemote home = (CabinHomeRemote)
javax.rmi.PortableRemoteObject.
narrow(obj,CabinHomeRemote.class);
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
28
14
Clase bean: TravelAgentBean (II)
[...]
Vector vect = new Vector();
for (int i = 1; ; i++) {
Integer pk = new Integer(i);
CabinRemote cabin = null;
try {
cabin = home.findByPrimaryKey(pk);
} catch(javax.ejb.FinderException fe) {
break;
}
// Check to see if the bed count and ship ID match.
if (cabin != null &&
cabin.getShipId() == shipID &&
cabin.getBedCount() == bedCount) {
String details =
i+","+cabin.getName()+","+cabin.getDeckLevel();
vect.addElement(details);
}
}
[...]
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
2005
29
Clase bean: TravelAgentBean (III)
[...]
String [] list = new String[vect.size()];
vect.copyInto(list);
return list;
} catch(Exception e) {throw new EJBException(e);}
}
private javax.naming.Context getInitialContext()
throws javax.naming.NamingException {
Properties p = new Properties();
// ... Specify the JNDI properties specific to the vendor.
return new javax.naming.InitialContext(p);
}
[...]
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
30
15
Clase bean: TravelAgentBean (IV)
[...]
public
public
public
public
void
void
void
void
ejbRemove(){}
ejbActivate(){}
ejbPassivate(){}
setSessionContext
(javax.ejb.SessionContext cntx){}
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
31
Cliente de TravelAgentEJB (I)
public class Client_3 {
public static int SHIP_ID = 1;
public static int BED_COUNT = 3;
public static void main(String [] args) {
try {
Context jndiContext = getInitialContext();
Object ref = jndiContext.lookup("TravelAgentHome");
TravelAgentHomeRemote home = (TravelAgentHomeRemote)
PortableRemoteObject.
narrow(ref,TravelAgentHomeRemote.class);
TravelAgentRemote travelAgent = home.create();
[...]
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
32
16
Cliente de TravelAgentEJB (II)
[...]
// Get a list of all cabins on ship 1 with a bed count of 3.
String list [] = travelAgent.listCabins(SHIP_ID,BED_COUNT);
for(int i = 0; i < list.length; i++){
System.out.println(list[i]);
}
} catch(java.rmi.RemoteException re){re.printStackTrace();}
catch(Throwable t){t.printStackTrace();}
System.exit(0);
}
static public Context getInitialContext() throws Exception {
Properties p = new Properties();
//specify the JNDI properties specific to thevendor
return new InitialContext(p);
}
}
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
33
Patrón FAÇADE
Ÿ Esconde al cliente la complejidad del modelo de EJBs
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
34
17
Excepciones
Ÿ RemoteException: (RMI) problemas de
comunicación remota
Ÿ NamingException: (JNDI) problemas en el
servicio de nombres (p.ej. no se encuentra el
nombre buscado)
Ÿ Y otras
Ÿ Además, la aplicación debería definir sus
propias excepciones, que se lanzan cuando
hay problemas en el ejecución en la lógica de
negocio
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
35
Contenido
Ÿ Caso de estudio
Ÿ Gestión de recursos
– Pooling de instancias
– Activación/pasivación
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
36
18
Pooling de instancias
Ÿ Los clientes no acceden a las instancias
directamente, sino a través de objetos EJB
(implementación del component interface)
Ÿ El servidor mantiene un pool de instancias,
que se asocian a los objetos EJB cuando se
requiere
Ÿ Manejo de recursos más eficiente
Ÿ Se aplica a entity beans y a stateless session
beans
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
37
Ciclo de vida de la instancia
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
38
19
Asignación de una instancia del pool
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
39
Swapping de instancias
Ÿ Los stateless session beans no mantienen
ningún estado
– cada cliente puede usar para cada invocación a un
método del objeto EJB una instancia distinta
– Los stateless session beans se declaran como
tales en el deployment descriptor (pero se
codifican de la misma forma que los stateful)
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
40
20
Ejemplo swapping
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
41
Activación/pasivación
Ÿ Los stateful session beans no participan en pooling
de instancias
– el estado de la conversación con el cliente debe mantenerse
durante toda la vida del servicio al cliente
Ÿ El servidor usa activación/pasivación para optimizar
la gestión de recursos:
– Pasivación: disociación del objeto EJB y la instancia del
bean, y serialización del estado de la instancia a
almacenamiento secundario
– Activación: restauración del estado de la instancia relativa al
objeto EJB
Ÿ Mecanismo transparente al usuario
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
42
21
Proceso activación/pasivación
2005
Software de Comunicaciones (c) UC3M Natividad Martínez, Ignacio Ramos Zapata
43
22
Descargar