11. Programación Avanzada (EJBs)

Enterprise beans son componentes de J2EE que implementan la tecnología Enterprise JavaBeans (EJB).

Enterprise beans corren dentro de un EJB container, un runtime environment dentro del Application Server.

Cuándo emplear Enterprise Beans

Se debe considerar el uso de enterprise beans si la aplicación presenta alguno de los siguientes requerimientos:

  • La aplicación debe ser escalable. Crecimiento de gran número de usuarios, probablemente se requiera de distribuir los componentes en distintas máquinas. No sólo los ejbs de una aplicación pueden correr en diferentes máquinas, su localización permanece transparente para los clientes.
  • Transacciones deben asegurar la integridad de los datos. Enterprise beans soportan transacciones, mecanismos de acceso a objetos compartidos.
  • La aplicación tendrá una variedad de clientes. Con solo unas líneas de código, clientes remotos pueden localizar fácilmente ejbs. Estos clientes pueden ser delgados, variados y numerosos.

 

Tipos de Enterprise Beans

 

Table 23-1 Enterprise Bean Types Enterprise Bean Type Purpose
Session

Realiza una tarea para un cliente, implementa un web service

Tipos

  • Un stateless session bean no mantiene un estado conversacional con el cliente
  • En un stateful session bean, las instancias de las variables representan el estado de una sesión
Entity

Representa un objeto que existe en almacenamiento persistente

  • Persistence
  • Shared Access
  • Primary Key
  • Relationships

Tipos

  • Container-managed persistence (CMP)
  • Bean-managed persistence (BMP)
Message-Driven Actua como un listener del Java Message Service API, procesando mensajes de manera asíncrona

 

Para desarrollar una enterprise bean, se deben proveer los siguientes archivos:

  • Deployment descriptor : Un archivo XML que especifica información acerca de los beans, como su persistencia, nivel de transacciones.
  • Enterprise bean class : Implementa los métodos definidos en las interfaces.
  • Interfaces : Remote y home interfaces son requeridas para acceso remoto. Para acceso local, las local y local home interfaces are required. Para acceso por Web service clients, la interface Web service endpoint.
  • Helper classes : Otras clases necesarias por el enterprise bean class, tales como exception y utility classes.

 

 

Table 23-2 Naming Conventions for Enterprise Beans  Item Syntax Example
Enterprise bean name (DD)     < name >Bean AccountBean
EJB JAR display name (DD)     < name >JAR AccountJAR
Enterprise bean class business and life-cycle implementation < name >Bean AccountBean
Home interface life-cycle outside container javax.ejb.EJBHome < name >Home AccountHome
Remote interface business outside container javax.ejb.EJBObject < name > Account
Local home interface life-cycle inside containe javax.ejb.EJBLocalHome < name >LocalHome AccountLocalHome
Local interface business inside container javax.ejb.EJBLocalObject < name > Local AccountLocal
Abstract schema (DD)     < name > Account
DD deployment descriptor.

 

 

   1:package com.titan.travelagent;
   2:
   3:import com.titan.cabin.CabinRemote;
   4:import com.titan.cabin.CabinHomeRemote;
   5:import java.rmi.RemoteException;
   6:import javax.naming.InitialContext;
   7:import javax.naming.Context;
   8:import javax.ejb.EJBException;
   9:import java.util.Properties;
  10:import java.util.Vector;
  11:
  12:public class TravelAgentBean implements javax.ejb.SessionBean 
  13:{
  14:
  15:   public void ejbCreate() 
  16:   {
  17:      // Do nothing.
  18:   }
  19:
  20:   public String [] listCabins(int shipID, int bedCount) 
  21:   {
  22:      try 
  23:      {
  24:         javax.naming.Context jndiContext = new InitialContext();
  25:         Object obj = 
  26:            jndiContext.lookup("java:comp/env/ejb/CabinHomeRemote");
  27:
  28:
  29:         CabinHomeRemote home = (CabinHomeRemote)
  30:            javax.rmi.PortableRemoteObject.narrow(obj,CabinHomeRemote.class);
  31:
  32:         Vector vect = new Vector();
  33:         for (int i = 1; ; i++) 
  34:         {
  35:            Integer pk = new Integer(i);
  36:            CabinRemote cabin = null;
  37:            try 
  38:            {
  39:               cabin = home.findByPrimaryKey(pk);
  40:            } 
  41:            catch(javax.ejb.FinderException fe) 
  42:            {
  43:               System.out.println("Caught exception: "+fe.getMessage()+" for pk="+i); 
  44:               break;
  45:            }
  46:            // Check to see if the bed count and ship ID match.
  47:            if (cabin != null &&
  48:                cabin.getShipId() == shipID && 
  49:                cabin.getBedCount() == bedCount) 
  50:            {
  51:               String details = 
  52:                  i+","+cabin.getName()+","+cabin.getDeckLevel();
  53:               vect.addElement(details);
  54:            }
  55:         }
  56:        
  57:         String [] list = new String[vect.size()];
  58:         vect.copyInto(list);
  59:         return list;
  60:       
  61:      } 
  62:      catch(Exception e) 
  63:      {
  64:         throw new EJBException(e);
  65:      }    
  66:   }
  67:
  68:   public void ejbRemove(){}
  69:   public void ejbActivate(){}
  70:   public void ejbPassivate(){}
  71:   public void setSessionContext(javax.ejb.SessionContext cntx){}
  72:}
 
   1:package com.titan.travelagent;
   2:
   3:import java.rmi.RemoteException;
   4:import javax.ejb.CreateException;
   5:
   6:public interface TravelAgentHomeRemote extends javax.ejb.EJBHome {
   7:
   8:    public TravelAgentRemote create()
   9:        throws RemoteException, CreateException;
  10:
  11:}
 
   1:package com.titan.travelagent;
   2:
   3:import java.rmi.RemoteException;
   4:import javax.ejb.FinderException;
   5:
   6:public interface TravelAgentRemote extends javax.ejb.EJBObject {
   7:
   8:    // String elements follow the format "id, name, deck level"
   9:    public String [] listCabins(int shipID, int bedCount)
  10:        throws RemoteException;
  11:
  12:}
 

 

   1:package com.titan.cabin;
   2:
   3:import javax.ejb.EntityContext;
   4:import javax.ejb.CreateException;
   5:
   6:public abstract class CabinBean 
   7:   implements javax.ejb.EntityBean 
   8:{
   9:
  10:   public Integer ejbCreate(Integer id) 
             throws CreateException
  11:   {
  12:      this.setId(id);
  13:      return null;
  14:   }
  15:   public void ejbPostCreate(Integer id)
  16:   {
  17:   }
  18:   
  19:   public abstract void setId(Integer id);
  20:   public abstract Integer getId();
  21: 
  22:   public abstract void setShipId(int ship);
  23:   public abstract int getShipId( );
  24:
  25:   public abstract void setName(String name);
  26:   public abstract String getName( );
  27:
  28:   public abstract void setBedCount(int count);
  29:   public abstract int getBedCount();
  30:
  31:   public abstract void setDeckLevel(int level);
  32:   public abstract int getDeckLevel();
  33:
  34:   public void setEntityContext(EntityContext ctx) 
  35:   {
  36:      // Not implemented.
  37:   }
  38:   public void unsetEntityContext() 
  39:   {
  40:      // Not implemented.
  41:   }
  42:   public void ejbActivate() 
  43:   {
  44:      // Not implemented.
  45:   }
  46:   public void ejbPassivate() 
  47:   {
  48:      // Not implemented.
  49:   }
  50:   public void ejbLoad() 
  51:   {
  52:      // Not implemented.
  53:   }
  54:   public void ejbStore() 
  55:   {
  56:      // Not implemented.
  57:   }
  58:   public void ejbRemove() 
  59:   {
  60:      // Not implemented.
  61:   }
  62:}
   1:package com.titan.cabin;
   2:
   3:import java.rmi.RemoteException;
   4:import javax.ejb.CreateException;
   5:import javax.ejb.FinderException;
   6:
   7:public interface CabinHomeRemote extends javax.ejb.EJBHome 
   8:{
   9:   public CabinRemote create(Integer id)
  10:      throws CreateException, RemoteException;
  11:   
  12:   public CabinRemote findByPrimaryKey(Integer pk)
  13:      throws FinderException, RemoteException;
  14:}
 
   1:package com.titan.cabin;
   2:
   3:import java.rmi.RemoteException;
   4:
   5:public interface CabinRemote extends javax.ejb.EJBObject 
   6:{
   7:   public String getName() throws RemoteException;
   8:   public void setName(String str) throws RemoteException;
   9:   public int getDeckLevel() throws RemoteException;
  10:   public void setDeckLevel(int level) throws RemoteException;
  11:   public int getShipId() throws RemoteException;
  12:   public void setShipId(int sp) throws RemoteException;
  13:   public int getBedCount() throws RemoteException;
  14:   public void setBedCount(int bc) throws RemoteException; 
  15:}
 
   1:package com.titan.clients;
   2:
   3:import com.titan.travelagent.TravelAgentHomeRemote;
   4:import com.titan.travelagent.TravelAgentRemote;
   5:
   6:import javax.naming.InitialContext;
   7:import javax.naming.Context;
   8:import javax.naming.NamingException;
   9:import javax.ejb.CreateException;
  10:import javax.rmi.PortableRemoteObject;
  11:
  12:import java.rmi.RemoteException;
  13:
  14:public class Client_3 
  15:{
  16:   public static int SHIP_ID = 1;
  17:   public static int BED_COUNT = 3;
  18:
  19:   public static void main(String [] args) 
  20:   {
  21:      try 
  22:      {
  23:         Context jndiContext = getInitialContext();
  24:           
  25:         Object ref = jndiContext.lookup("TravelAgentHomeRemote");
  26:               
  27:         TravelAgentHomeRemote home = (TravelAgentHomeRemote)
  28:            PortableRemoteObject.narrow(ref,TravelAgentHomeRemote.class);
  29:        
  30:         TravelAgentRemote travelAgent = home.create();
  31:        
  32:         // Get a list of all cabins on ship 1 with a bed count of 3.
  33:         String list [] = travelAgent.listCabins(SHIP_ID,BED_COUNT);
  34:        
  35:         for(int i = 0; i < list.length; i++)
  36:         {
  37:            System.out.println(list[i]);
  38:         }
  39:      } 
  40:      catch(java.rmi.RemoteException re)
  41:      {
  42:         re.printStackTrace();
  43:      }
  44:      catch(Throwable t)
  45:      {
  46:         t.printStackTrace();
  47:      }
  48:   }
  49:
  50:   static public Context getInitialContext() throws Exception 
  51:   {
  52:      return new InitialContext();
  53:      /**** context initialized by jndi.properties file
  54:        java.util.Properties p = new java.util.Properties();
  55:p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
  56:        p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");
  57:        p.put(Context.PROVIDER_URL, "localhost:1099");
  58:        return new javax.naming.InitialContext(p);
  59:      */
  60:   }
  61:
  62:}
  63:
      
 
   1:<?xml version="1.0"?>
   2:
   3:<jboss>
   4:     <enterprise-beans>
   5:       <entity>
   6:         <ejb-name>CabinEJB</ejb-name>
   7:         <jndi-name>CabinHomeRemote</jndi-name>
   8:       </entity>
   9:       <session>
  10:         <ejb-name>TravelAgentEJB</ejb-name>
  11:         <jndi-name>TravelAgentHomeRemote</jndi-name>
  12:         <ejb-ref>
  13:           <ejb-ref-name>ejb/CabinHomeRemote</ejb-ref-name>
  14:           <jndi-name>CabinHomeRemote</jndi-name>
  15:         </ejb-ref>
  16:       </session>
  17:     </enterprise-beans>
  18:</jboss>
      
 
   1:<?xml version="1.0"?>
   2:
   3:<!DOCTYPE ejb-jar PUBLIC 
   4:"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" 
   5:"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
   6:
   7:<ejb-jar>
   8:
   9: <enterprise-beans>
  10:   <entity>
  11:      <ejb-name>CabinEJB</ejb-name>
  12:      <home>com.titan.cabin.CabinHomeRemote</home>
  13:      <remote>com.titan.cabin.CabinRemote</remote>
  14:      <ejb-class>com.titan.cabin.CabinBean</ejb-class>
  15:      <persistence-type>Container</persistence-type>
  16:      <prim-key-class>java.lang.Integer</prim-key-class>
  17:      <reentrant>False</reentrant>
  18:      <cmp-version>2.x</cmp-version>
  19:      <abstract-schema-name>Cabin</abstract-schema-name>
  20:      <cmp-field><field-name>id</field-name></cmp-field>
  21:      <cmp-field><field-name>name</field-name></cmp-field>
  22:      <cmp-field><field-name>deckLevel</field-name></cmp-field>
  23:      <cmp-field><field-name>shipId</field-name></cmp-field>
  24:      <cmp-field><field-name>bedCount</field-name></cmp-field>
  25:      <primkey-field>id</primkey-field>
  26:      <security-identity><use-caller-identity/></security-identity>
  27:   </entity>
  28:
  29:   <session>
  30:     <ejb-name>TravelAgentEJB</ejb-name>
  31:     <home>com.titan.travelagent.TravelAgentHomeRemote</home>
  32:     <remote>com.titan.travelagent.TravelAgentRemote</remote>
  33:     <ejb-class>com.titan.travelagent.TravelAgentBean</ejb-class>
  34:     <session-type>Stateless</session-type>
  35:     <transaction-type>Container</transaction-type>
  36:
  37:     <ejb-ref>
  38:       <ejb-ref-name>ejb/CabinHomeRemote</ejb-ref-name>  
  39:       <ejb-ref-type>Entity</ejb-ref-type>
  40:       <home>com.titan.cabin.CabinHomeRemote</home>
  41:       <remote>com.titan.cabin.CabinRemote</remote>
  42:     </ejb-ref>
  43:
  44:     <security-identity><use-caller-identity/></security-identity>
  45:
  46:  </session>
  47: </enterprise-beans>
  48:
  49: <assembly-descriptor>
  50:
  51:   <security-role>
  52:      <description>
  53:         This role represents everyone who is allowed full access to the beans.
  54:      </description>
  55:     <role-name>everyone</role-name>
  56:   </security-role>
  57:
  58:   <method-permission>
  59:     <role-name>everyone</role-name>
  60:     <method>
  61:       <ejb-name>CabinEJB</ejb-name>
  62:       <method-name>*</method-name>
  63:     </method>
  64:     <method>
  65:       <ejb-name>TravelAgentEJB</ejb-name>
  66:       <method-name>*</method-name>
  67:     </method>
  68:   </method-permission>
  69:
  70:   <container-transaction>
  71:     <method>
  72:       <ejb-name>CabinEJB</ejb-name>
  73:       <method-name>*</method-name>
  74:     </method>
  75:     <method>
  76:        <ejb-name>TravelAgentEJB</ejb-name>
  77:        <method-name>*</method-name>
  78:     </method>
  79:     <trans-attribute>Required</trans-attribute>
  80:   </container-transaction>
  81:
  82: </assembly-descriptor>
  83:
  84:</ejb-jar>
      
 

EJB-EXAMPLE

 

Java Enterprise Application Server Platform Edition