CursoJbossJavaEnterpriseEdition

J2EE #

Introducción a J2EE #

Características generales que toda plataforma de desarrollo/ejecución debería cumplir:
  • Escalabilidad administrador/desarrollador
  • Mantenibilidad administrador
  • Fiabilidad administrador
  • Disponibilidad administrador
  • Extensibilidad administrador/desarrollador
  • Manejabilidad administrador/desarrollador
  • Seguridad adminsitrador/desarrollador
  • Rendimiento administrador/desarrollador
Hay tres plataformas de desarrollo orientadas de manera distinta:
  • JME (java micro edition) orientada al desarrollo de aplicaciones para dispositivos móviles
  • JSE (java standard edition) orientada al desarrollo de aplicaciones de escritorio
  • JEE (java enterprise edition) orientada al desarrollo de aplicaciones empresariales multicapa y distribuidas
Las características principales de Java EE son:
  • Java EE está construida sobre Java SE (no lo reemplaza)
  • Se agregan servicios necesarios en aplicaciones empresariales
  • Facilita el desarrollo de aplicaciones multicapa
    • presentation layer
    • obusiness rules layer
    • data access layer
  • Permite el desarrollo de aplicaciones escalables
  • Requiere 3 componentes de software fundamentales en el servidor (application server)
    • contenedor de servlets
    • contenedor de Web Services
    • contenedor de enterprise java beans (EJB)
<img src="/image/image_gallery?img_id=12480&t=1206439864889" />

Arquitectura Java EE #

https://wiki.zylk.net:448/zwiki CursoJboss J2EE?action AttachFile do=get&target=overview-multitieredApplications.gif <img src="/image/image_gallery?img_id=12484&t=1206441227920" /> Como se ve en la Figura anterior, la estructura de los contenedores se puede separar en 4/3 capas
  • Capa de cliente
La función básica de esta capa es la de interacción con el usuario y la de prentación de los datos. En Java EE se especifican tres tipos de de componentes para la visialización/interacción con la capa de cliente. El navegador (HTML,XHML, applets). Aplicaciones de escritorio Java GUI. Otros dispositivos moviles.
  • Capa de Web
Soporta la lógica de persentación de la aplicación Java EE. Todas las tecnologías (jsp, jsf, servlets etc..) que se desarrollan dentro de este contenedor, se orientan al modelo petición respuesta (request-response)
  • Capa de negocio
Soporta la lógica de negocio de las aplicaciones, en realidad la plataforma Java EE está orientada a la gran empresa y en esta capa no se trata de representar de una manera atómica la lógica de negocio de un aplicativo en concreto, sino de representar de manera holistica los procesos de la empresa para poder reutilizar los componentes creados en varias aplicaciones y poder reutilizar el código. En esta capa/contenedor, se encuentran dos tipos de componentes principalmente los EJBs y los servicios web.
  • Capa del sistema de información (base de datos)
Soporta en último lugar la persistencia de los datos, se puede entender como un almacén de información (EIS enterprise information system). En realidad no es un capa como las otras tres, ya que Java EE no define como deben ser los componentes de esta capa (bases de datos, ERPs, recursos etc..) lo que define Java EE es mas bien la forma de acceder a ellos y los ACLs de los recursos anteriormente citados. La otra parte importante además de la estructura de capas de la plataforma son los apis/recursos que la plataforma ofrece a los desarrolladores y administradores para que los sistemas Java EE sean más mantenibles. Los principales APIs/servicios son:
  • JDBC
  • JNDI
  • JMS
  • JavaMail * JAF
  • JTA
  • JAX
  • JCA
  • JAAS

Comparativa Java EE vs .NET #

Existen en el mercado dos plataformas que nacen con una oreintación similar, la promovidad por SUN (J2EE, Java EE) y la promovidad por microsoft (.NET) cabe preguntarse por tanto que las distingue y que puntos en común tienen. Pros:
  • Multiplataforma (No asi .NET)
  • Especificaciones realizadas por un organismo de control (JCP) (Las realiza Microsoft)
  • Independencia con el proveedor (varias implementaciones de las especificaciones) (Solo existe una implementación, la de microsoft)
  • Madurez, lleva en el mercado desde 1997 (Es relativamente joven)
  • Código libre, licenciado bajo GPL
Contras:
  • Solo se puede programar en JAVA (otros lenguajes a traves de CORBA o JNI) (.NET Permite mas lenguajes de programación)
  • Es una plataforma compleja, curva de aprendizaje elevada (es relativamente sencillo programar)
  • A veces hay demasiadas alternativas para cada problema, con lo que puede resultar confusa la elección

Componentes y Containers #

Las aplicaciones Java EE, estan construidas alrededor de lo que se llaman componentes. Un componente es un parte de código, auto-suficiente(auto-contenido) que tiene una funcionalidad concreta. El componente se comunica con otros componentes se definene el siguiente conjunto de componentes:
  • Los applets son componentes de la capa de cliente
  • Los Servlets, JSF, JSP etc.. son componentes de la capa web de servidor
  • Los EJBs junto con los web-services son los componentes que encierran la lógica de negocio, en la capa de negocio.
Los componentes se escriben en java, Se distinguen de las clases de java en su ciclo de vida. En aplicaciones clásicas que no cumplian con los estandares de Java EE la lógica de negocio se codificaba en un conjunto de clases. En la visión enterprise esta lógica además de codiifcarse en códio java debe cumplir una serie de especificaciones para poder desplegar dichos componentes en el contendor de correspondiente (Contendor de servlets, contenedor de EJBs, contenedor de Web-services). En este contenedor se vertifica que cumplen los estandares y que estan dentro del ciclo de vida de cada componente, y que pueden ser controlados por su respectivo contenedor. Por ejemplo el ciclo de vida de un servlet dentro de un contenedor de servlets sería (tener en cuenta que ciclo de vida de un componente esta controlado por su contenedor) Si se mappea un tipo de petición (url) a un servlet (web.xml) el contenedor responsable de dicho servlet realiza la siguientes acciones: 1. Si la instancia del servlet no existe en el contenedor: 1. Se carga la clase (servlet) 2. Se crea una instancia de dicha clase (esta instancia responderá a todas las peticiones que se hagan a la url mapeada) 3. Se inicializa la instancia, invocando al metodo initialize del servlet 2. Se invoca al metodo service (pasandole el request, response) cada vez que el contenedor recibe una petición que corresponde a la url mapeada en el web.xml 3. Si el contenedor necesita eliminar el servlet, (un-deploy), se hace invocando al metodo destroy. <img src="/image/image_gallery?img_id=12492&t=1206439990280" />

Aplicaciones Web, empaquetados war #

In the Java EE architecture, web components and static web content files such as images are called web resources. A web module is the smallest deployable and usable unit of web resources. A Java EE web module corresponds to a web application as defined in the Java Servlet specification. Segun se define en las especificaciones de la arquitectura Java EE, los componentes web y los contenidos estáticos se denominan recursos. Un .war (WebARchive) es el recursos mínimo que se puede desplegar en un contenedor. Un WAR, corresponde a una aplicación web definida en las especificaciones (java servlets). La estructura de un war es la siguiente. <img src="/image/image_gallery?img_id=12496&t=1206440024095" /> Comos se ve tiene que tener una estructura especifica, Del documentRoot, cuelgan los jsp y los contenidos estáticos, imágenes, applets etc...además tiene un directorio WEB/INF que contiene los siguientes subdirectorios y archivos:
  • web.xml el archivo en el que se describen los mapeos y las características de la aplicacion
  • Tag library tlds
  • classes: Directorio que contiene las clases del aplicativo
  • lib: librerias JAR
Ciclo de vida de un war:
  • deploy
Fase de despliegue del war en ella se ejecutan los listeners concretos definidos en el web.xml poir ejemplo: code<listener>
     <listener-class>net.zylk.a2.app.event [[OnStartUp|OnStartUp]] /listener-class>
</listener> /code ejecuta en la fase de despliegue la clase OnStartUp que debe implementar la interfaz / ServletContextListener / codepublic void contextInitialized ServletContextEvent parm1) { recogemos el archivo principal de configuracion de la aplicación ResourceBundle resource = ResourceBundle getBundle(this.getConfigFilePath()); CARGAMOS EL LOGGER try {
 [[InputStream|InputStream]] isLogger = parm1.getServletContext().getResourceAsStream(resource.getString(this.getLoggerConfigFileParam()));
 [[LogManager|LogManager]] getLogManager().readConfiguration(isLogger);
 logger.info("arrancando el logger de la aplicacion");
 logger.finest("leido el archivo de configuracion del logger: "+resource.getString(this.getLoggerConfigFileParam()));
} catch (Exception io) {
 Handler handler = null;
 try
 {
  handler = new [[FileHandler|FileHandler]] resource.getString(this.getLoggerConfigFileOnErrorParam()));
 }
 catch(IOException io2)
 {
  io2.printStackTrace();
 }
 handler.setLevel(Level.SEVERE);
 handler.setFormatter(new [[SimpleFormatter|SimpleFormatter]] ));
 logger.addHandler(handler);
 logger.severe("no se ha podido inicializar la configuracion del logger leyendo "+resource.getString(this.getLoggerConfigFileParam()));
 logger.severe("no se ha podido inicializar la configuracion del logger error "+io);
}

public void contextDestroyed ServletContextEvent arg0) { ejecutado en el un-deploy del war } abstract public String getConfigFilePath(); protected String getLoggerConfigFileParam() {

        return LOGGER_CONFIG_FILE_PARAM;
} protected String getTorqueConfigFileParam() {
        return TORQUE_CONFIG_FILE_PARAM;
} protected String getLoggerConfigFileOnErrorParam() {
        return LOGGER_CONFIG_FILE_ON_ERROR_PARAM;
} /code
  • un-deploy
En esta fase se ejecuta el metodo contextDestroyed()

Apliciones Enterprise, empaquetados ear #

<img src="/image/image_gallery?img_id=12460&t=1206439701719" /> An EAR file is used to package one or more J2EE modules into a single module so that they can have aligned classloading and deployment into a server. Un Archivo tipo ear (emapaquetado ear) contiene modulos de Java EE y sus archivos de despliegue. Los archivos de despliegue son archivos xml donde se describe las características de despligue del aplicativo, modulo o componente que se va a desplegar. Como el contenido de los archivos xml es declarativo las porpiedades que se definene en estos archivos pueden ser modificadas sin necesidad de modifiacr el código fuente, ya que se leen en tiempo de ejecución. Un descriptor contiene informacion sobre:
  • EJB components
  • Web components
  • Client components
  • Alternate Deployment Descriptor for theses components
  • Security role.
ejemplo de un application.xml code<application xmlns="http://java.sun.com/xml/ns/j2ee"
      xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance"]
      xsi:schemaLocation="[http://java.sun.com/xml/ns/j2ee]
      [http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"]
      version="1.4">
  <display-name>Simple example of application</display-name>
  <description>Simple example</description>
  
  <module>
    <ejb>ejb1.jar</ejb>
  </module>
  <module>
    <ejb>ejb2.jar</ejb>
  </module>
  
  <module>
    <web>
      <web-uri>web.war</web-uri>
      <context-root>web</context-root>
    </web>
  </module>
</application> /code

Servicios / API #

Introduccion #

Enterprise JavaBeans Technology #

Son los componentes de la plataforma Java EE que implementan la logica del negocio, es decir es un conjunto de metodos y campos (programacion orientada a objetos), en los que se implementa la lógica de negocio. La idea es hacer piezas reutilizables, en modo stand alone, o en conjunción con el resto de la arquitectura distribuida en una plataforma Java EE. Enterprise Java Beans es uno de los componente principales del grupo de especificaciones Java EE, a través de EJB's se define una estructura en la cual es posible manipular e interactuar con procesos e información que residen en diversos ambientes computacionales desde MainFrames hasta Bases de Datos. Estos componentes (EJB's) contemplan diversas características esperadas de una aplicación empresarial como:
  • Control de Transacciones
  • Seguridad
  • Threading
  • Propagación de Transacciones
Dichos componentes son ejecutados dentro de un Application Server de los cuales existen aproximadamente bastantes en el mercado: además cabe mencionarse que actualmente existen tres tipos principales de EJB's los cuales serán explorados a fondo en el resto de este curso. Existen dos/tres tipos de EJBs
  • essions beans (orientados a la conexión sincrona, petición respuesta, y cuando el cliente termina la comunicación la instanaci del ejb desaparece)
  • message-drive beans (orientados a la conexión asincrona, no necesitan sesion para su ejecución, son los encargados de la comunicación por medio de JMS (java mesage service) )
  • En la anterior especificación, J2EE 1.4, existían EJBs de entidad (entity beans), que representaban, la capa de persistencia. En esta versión se ha intentado trasladar el concepto de persistencia a otro API, persistence API entities.

Java Servlet Technology #

Es la tecnologia definida para comunicación con los navegadores por medio del modelo de petición-respuesta. (request-response).

JavaServer Pages Technology #

Conjuntamente con la tecnologia de los servlets, se utiliza para presentar los datos al navegador. Tipicamente en un patron MVC la parte de presentación la harían los jsp. Se trata con ello de independizar lo más posible la vista del resto de las capas del patrón.

JavaServer Pages Standard Tag Library #

Los jsp llevan partes de código java, que el servidor interpreta y devuelve en un formato comprensible para el navegador, este código se puede escribir directamente o haciendo uso de una tags especiales (denominadas tlds) que encapsulan el código java.

JavaServer Faces #

Es un framework de desarrollo orientado para crear la VISTA en el modelo MVC. Las principales características del framework son:
  • Validación
  • Tratamiento de eventos
  • Conversión de los datos entre las capas Modelo-Componente
  • Es capaz de lanzar los eventos necesarios para que el modelo manipule el valor de los objetos
  • Aporta la paginación a la capa de presentación

Java Message Service API #

El API JMS es un estandar que permite a los componentes de las aplicaciones Java EE crear enviar leer etc.. mensajes de una manera estandar. Aporta la comunicación, estandar, necesaria para una arquitectura distribuida.

Java Transaction API #

El API JTA, aporta una interfaz para definir las tranasacciones entre los componentes. Por ejemplo si tu aplicacione hacer dos acciones que dependen una de otra (por ejemplo dos accesos a base de datos), el API JTA define una manera estandar por la cual se define cuando la transacción se ha realizado completamente, y además incluye las tareas de rollback commit etc.. Eso si hay que tener en cuenta que no es una implementación sino una interfaz que nuestros procesos deberían implementar

JavaMail API #

API para el envio de notificaciones por medio de emails, tiene dos partes:
  • Interfaz para que las aplicaciones lo invoquen directamente
  • Interfaz a modo de servicio

Java API for XML Processing #

API para el procesado de XML (JAXP), soporta el acceso a documentos XML por medio de su representación DOM, o SAX, puede porcesar documentos XML por medio de XSLT.

Java API for XML Web Services (JAX-WS) #

API para el uso de web-services.

SOAP with Attachments API for Java #

SOAP (siglas de Simple Object Access Protocol) es un protocolo estándar creado por Microsoft, IBM y otros, está actualmente bajo el auspicio de la W3C que define cómo dos objetos en diferentes procesos pueden comunicarse por medio de intercambio de datos XML. SOAP es uno de los protocolos utilizados en los servicios Web La plataforma Java EE, tiene un API para poder tratar dicha comunicación.

Java Database Connectivity API #

API para acceso a los datos de una base de datos. Permite ejecutar comandos de SQL desde una aplicación, (desde un ejb, servlet, o jsp). Al igual que JavaMail tiene dos partes:
  • API para acceso directo desde una aplicación
  • Un interfaz que se puede usar como un servicio (recogido desde el JNDI)
De la wikipedia: JDBC es el acrónimo de Java Database Connectivity, un API que permite la ejecución de operaciones sobre bases de datos desde el lenguaje de programación Java independientemente del sistema de operación donde se ejecute o de la base de datos a la cual se accede utilizando el dialecto SQL del modelo de base de datos que se utilice. El API JDBC se presenta como una colección de interfaces Java y métodos de gestión de manejadores de conexión hacia cada modelo específico de base de datos. Un manejador de conexiones hacia un modelo de base de datos en particular es un conjunto de clases que implementan las interfaces Java y que utilizan los métodos de registro para declarar los tipos de localizadores a base de datos (URL) que pueden manejar. Para utilizar una base de datos particular, el usuario ejecuta su programa junto con la librería de conexión apropiada al modelo de su base de datos, y accede a ella estableciendo una conexión, para ello provee en localizador a la base de datos y los parámetros de conexión específicos. A partir de allí puede realizar con cualquier tipo de tareas con la base de datos a las que tenga permiso: consultas, actualizaciones, creado modificado y borrado de tablas, ejecución de procedimientos almacenados en la base de datos, etc.

Java Persistence API #

Es un conjunto de estandares que tratan de definir lo que es la persistencia. Se definen tres areas:
  • El propio api de persistencia
  • Un query-language
  • Object/relational mapping metadata (para poder establecer la relación entre los objetos y las relaciones-tablas de una base de datos)

Java Naming and Directory Interface #

Servicio de directorio, permite a los programas buscar dentro de el arbol JNDI la información que requieren. Un uso tipico es por ejemplo publicar una conexión a base de datos en el arbol y que el una aplicacion la recoja y la utilice. Se puede hacer lo mismo con el servicio de envio de emails

Java Authentication and Authorization Service #

Define las especificaciones para que las aplicaciones Java EE sepan como deben hacer las autenticaciones

El arbol JNDI Java Naming and Directory Interface #

Encontrar objetos en un sistema de cierta complejidad puede ser un problema. ¿Dónde se ubican? ¿Cuales son sus características?. Necesitamos tener un sistema de nombrado que nos evite el problema de encontrarlo, sea cual sea su ubicación y la aplicación que lo utiliza. Esta es la funcion del arbol JNDI. El sistema de directorios y nombres de Java facilita el mantenimiento de aplicaciones, permitiendo a diversos programas localizar y recuperar objetos. En JNDI es un servicio de nombres. Cuando asociamos un nombre con un objeto hablamos de "unión (binding) del objeto". Un conjunto de uniones nombre-objeto es un contexto. Los contextos tienen también una relación jerárquica, como ocurre con el espacio de directorios y subdirectorios. Un sistema de nombrado tiene un espacio de nombres, que no es más que el conjunto de todos los contextos de dicho sistema. Es necesario ampliar el concepto de servicio de nombres para llegar al de servicio de directorio, donde se relacionan nombres de objeto con nombres de atributos, al igual que ocurre en unas páginas amarillas. De esta forma se enriquece el sistema de búsqueda, ya que no sólo buscamos por nombre de objeto (el nombre de una persona en las páginas amarillas), sino que además podemos buscar por un filtro. Un filtro de búsqueda es una consulta de objetos que tienen sus atributos asociados con ciertos valores. Por ejemplo, la búsqueda de personas en una guía telefónica que cumplan la condición de que su dirección es "Alcala 80". JNDI es un API definido para la plataforma Java EE que provee a las aplicaciones hechas en java de las funcionalidades de un directorio. Usando JNDI las aplicaciones escritas en java pueden alamcenar cualquier tipo de objeto, y hacer el resto de acciones típicas de un directorio, buscar, asociar atributos, recuperar dichos atributos etc... <img src="/image/image_gallery?img_id=12468&t=1206439752398" /> La idea de JNDI implica universalidad y abstracción: es un API genérico, de tal forma que es necesario integrarlo con otros sistemas de nombres. Para ello la arquitectura JNDI incluye un interfaz de provisión de servicio (service provider interface, SPI), que sirve de intermediario con otros proveedores de servicios de nombres/directorios. Las aplicaciones pueden almacenar factorias de objetos y sus configuraciones en un arbol usando el API JNDI. Para despues usar dichos objetos. JNDI permite separar la configuracion de la implementacion. Algunas de las factorias de objetos que se usan son:
  • JDBC DataSource * EJB Home interfaces
  • Java Messaging Service (JMS) connection factories
  • JavaMail connection factories
  • Global configuration constants
3.2.1. JNDI y JDBC Java Database Connectivity Ya hemos explicado que es JNDI y JDBC, ahora vamos a intentar sacar partido de ambos APIs para conseguir que los componentes de la plataforma Java EE sean mas reutilizables y mantenibles. El problema con las conexiones es que si se codifican en el código no son mantenibles por el administrador del sistema. la primera aproximación sería, que las aplicaciones utilicen un resource (.properties) para que los datos de la conexión fueran modificables por el administrador.
  • Esto se suele hacer pero no es estandar
La solución que se suele proponer es:
  • publicar la conexión en el jndi
  • recoger la conexión en la aplicación y utilizarala
Hacerlos asi tiene muchas ventajas:
  • una forma estandar de acceso al recurso
  • facil de mantener (bien directamente, bien por medio de JMX)
  • elega la responsabilidad del pool de conexiones en el application server
  • Centralizacion de los recursos
Ejemplo de xml (para jboss). Cuando el jboss encuentra este xml crea un pool de conexiones y lo publica en el JNDI code<?xml version="1.0" encoding="UTF-8"?>

<!-- The Hypersonic embedded database JCA connection factory config $Id: a2-app-ds.xml,v 1.1 2006/10/06 08:23:49 victor Exp $ --> <datasources>

   <local-tx-datasource>
      <!-- The jndi name of the [[DataSource|DataSource]]  it is prefixed with java:/ -->
      <!-- Datasources are not available outside the virtual machine -->
      <jndi-name>a2DS</jndi-name>
      <connection-url>jdbc:postgresql://localhost:5432/a2-db</connection-url>
      <driver-class>org.postgresql.Driver</driver-class>
      <!-- The login and password -->
      <user-name>a2User</user-name>
      <password>a2User</password>
      <!-- this will be run before a managed connection is removed from the pool for use by a client-->
      <check-valid-connection-sql>select 1</check-valid-connection-sql>
      <!-- The minimum connections in a pool/sub-pool. Pools are lazily constructed on first use -->
      <min-pool-size>1</min-pool-size>
      <!-- The maximum connections in a pool/sub-pool -->
      <max-pool-size>2</max-pool-size>
      <!-- The time before an unused connection is destroyed -->
      <idle-timeout-minutes>5</idle-timeout-minutes>
      <new-connection-sql>select 1</new-connection-sql>
     <track-statements/>
     <prepared-statement-cache-size>32</prepared-statement-cache-size>
   </local-tx-datasource>
</datasources>/code

Codigo java para acceso al recurso publicado:

code/ Obtain our environment naming context Context initCtx = new InitialContext ); Context envCtx = (Context) initCtx.lookup("java:comp/env"); Look up our data source DataSource ds = DataSource envCtx.lookup("a2DS"); Allocate and use a connection from the pool Connection conn = ds.getConnection(); ... use this connection to access the database ... conn.close(); /code Lo anterior sería una de las maneras estandares de hacer uso del arbol JNDI para publicar un recurso, en este caso una datasource (conexion por jdbc), y como recogerlo y utilizarlo en nuestros componentes.

JNDI y JavaMail #

Ya hemos explicado que es JNDI y JavaMail ahora vamos a intentar sacar partido de ambos APIs para conseguir que los componentes de la plataforma Java EE sean mas reutilizables y mantenibles. La idea es la misma que en el caso anterior con el JNDI-JDBC.

  • Publicar el recursos en el arbol JNDI
  • Recogerlo en la aplicación
  • Utilizarlo
Ejemplo de xml para publicar en el JNDI el recurso (ejemplo para jboss): code<?xml version="1.0" encoding="UTF-8"?> <!-- $Id: mail-service.xml,v 1.1 2006/10/05 15:37:10 gus Exp $ -->

<server>

  <!-- ==================================================================== -->
  <!-- Mail Connection Factory                                              -->
  <!-- ==================================================================== -->
  <mbean code="org.jboss.mail [[MailService|MailService]] 
         name="jboss:service=Mail">
    <attribute name="JNDIName">java:/Mail</attribute>
    <attribute name="User">User</attribute>
    <attribute name="Password">Password</attribute>
    <attribute name="Configuration">
       <!-- Test -->
       <configuration>
          <!-- Change to your mail server prototocol -->
          <property name="mail.store.protocol" value="imap"/>
          <property name="mail.transport.protocol" value="smtp"/>
          <!-- Change to the user who will receive mail  -->
          <property name="mail.user" value="nobody"/>
          <!-- Change to the mail server  -->
          <property name="mail.imap.host" value="mail.server.com"/>
          <!-- Change to the SMTP gateway server -->
          <property name="mail.smtp.host" value="mail.server.com"/>
          <!-- Change to the address mail will be from  -->
          <property name="mail.from" value="info@server.com"/>
          <!-- Enable debugging output from the javamail classes -->
          <property name="mail.debug" value="false"/>
       </configuration>
    </attribute>
  </mbean>
</server> /code Codigo java de ejemplo: codeProperties properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces NamingContextFactory ); properties.put(Context.PROVIDER_URL, "jnp:localhost:1099"); properties.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces"); properties.put("jnp.disableDiscovery", "true");

ctx = new InitialContext properties); JBoss Email Service ctx = (Context) ctx.lookup("java:"); mailSession = (Session) ctx.lookup("Mail");

-- Get hold of a POP3 message store, and connect to it -- if (null != mailSession) {

 store = mailSession.getStore("pop3");
store.connect(null, "", "");

-- Try to get hold of the default folder -- inboxFolder = store.getDefaultFolder();

-- ...and its INBOX -- inboxFolder = inboxFolder.getFolder("INBOX");

.... .... /code En este ejemplo se trata de ilustrar dos cosas:

  • Recogida del objeto (Session de javaMail)
  • Como se puede recoger el contexto de un servidor jnp, en este caso localhost, pero podría haber sido dentro de una arquitectura distribuida.
Hacerlos asi tiene muchas ventajas:
  • una forma estandar de acceso al recurso
  • facil de mantener (bien directamente, bien por medio de JMX)
  • delega la responsabilidad del envio de correos en el servidor de aplicaciones mas que en el código del desarrollador
  • Centralizacion de los recursos

JMX Java Management Extensions #

De la wikipedia Del acrónimo Java Management eXtensions, JMX es la tecnología que define una arquitectura de gestión, la API (Application Programming Interface), los patrones de diseño, y los servicios para la monitorización/administración de aplicaciones basadas en Java. Su versión 1.2 ha sido añadida al J2SE en su versión 5.0. Es decir es la herramienta/API para administrar los recursos de una aplicacion Java. Sirve para monitorizar/administrar las aplicacione Java. Sigue un modelo de tres capas:

JMX Java Management Extensions #

De la wikipedia Del acrónimo Java Management eXtensions, JMX es la tecnología que define una arquitectura de gestión, la API (Application Programming Interface), los patrones de diseño, y los servicios para la monitorización/administración de aplicaciones basadas en Java. Su versión 1.2 ha sido añadida al J2SE en su versión 5.0. Es decir es la herramienta/API para administrar los recursos de una aplicacion Java. Sirve para monitorizar/administrar las aplicacione Java. Sigue un modelo de tres capas:
  • Nivel de instrumentación (como debe definirse, que debe implementar, un recurso java para poder ser monitorizado/administrador por este API)
  • Nivel de agente (encargado de controlar las entidades de la capa de instrumentación)
  • Nivel de gestion (El nivel de gestión o adaptación es la encargada de adaptar las entidades externas que interactúan con al nivel de agente)
La instrumentalizacion se realiza por medio de MBeans. La idea es que todo recurso que se quiera monitorizar debe ser representado por un MBean, y asi los agentes podrán interactura con él. Creando instancias de dicho tipo, modificando sus atributos etc.. Existen varios tipos de MBean:
  • Standard MBean
De la forma más sencilla de instrumentar un recurso. Similar al modelo de componentes de JavaBeans y con una interface de gestión estática. Posee métodos para obtener y asignar valores a los atributos que se definen en el objeto implementado. Los métodos que expone el objeto son determinados en el momento de la compilación del mismo y no pueden ser modificados en tiempo de ejecución.
  • Dynamic MBean
Posee métodos genéricos para obtener, asignar valores e invocar callback. Los métodos toman entre sus argumentos el nombre del atributo cuyo valor se desea obtener, el nombre del atributo y el valor que se le quiere asignar.
  • Model MBean
Constituye un MBean dinámico, genérico y configurable que se utiliza para instrumentar recursos en tiempo de ejecución.
  • Open MBean
Este tipo de MBean permite utilizar objetos gestionados que son descubiertos en tiempo de ejecución. Lo normal es que los servidores de aplicaciones dispongan de herramientas para acceder al servidor de MBeans para que los gestores puedan administrar las aplicacione Un servidor de MBeans es debe permitir:
  • Localización
  • Filtrado por nombre o expresión
  • Monitorización de atributos
  • Descubrir otros agentes
  • Establecer relaciones entre MBeans
  • Carga dinámica
  • Programación de tareas
  • Definir jerarquías de agentes
Mas adelante veremos como implementa JBoss JMX y como utilizar la JMXConsole para administrar el servidor para :
  • Ver el arbol JNDI
  • Control de hilos
  • Ver el estado de la memoria usada por el servidor
  • Ver los componentes desplegador y administrar los ciclos de los mismos* Nivel de instrumentación (como debe definirse, que debe implementar, un recurso java para poder ser monitorizado/administrador por este API)

JMQ Java Message Queue #

Sistema de mensajería estandarizado. JBoss Tiene hecha su propia implementación por lo que se puede utilizar de manera transparente para el programador. La API de Servicios de Mensajería de Java (también conocido por sus siglas JMS), es un estandar de mensajería que permite a los componentes de aplicaciones basados en la plataforma de Java 2 crear, enviar, recibir y leer mensajes. También hace posible la comunicación confiable de manera síncrona y asíncrona. El servicio de mensajería también es conocido como Middleware Orientado a Mensajes (MOM por sus siglas en inglés) y es una herramienta universalmente reconocida para la construcción de aplicaciones empresariales. Al igual que en el caso del JNDI/JDBC Jboss hace uso de la publicación de los objetos en el arbol JNDI para que el servicio de colas necesario para la mensajeria pueda funcionar. code<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=order">
    <attribute name="JNDIName">queue [[TestQueue|TestQueue]] /attribute>
    <depends optional-attribute-name= [[DestinationManager|DestinationManager]] >jboss.mq:service [[DestinationManager|DestinationManager]] /depends>
</mbean> /code El código que haría uso de la cola podría ser: codepublic class SendRecvClient {
 static [[CountDown|CountDown]] done = new [[CountDown|CountDown]] 1);
 [[QueueConnection|QueueConnection]] conn;
 [[QueueSession|QueueSession]] session;
 Queue que;
 public static class [[ExListener|ExListener]] implements [[MessageListener|MessageListener]]  {
  public void onMessage(Message msg)
  {
   done.release();
   [[TextMessage|TextMessage]] tm =  [[TextMessage|TextMessage]]  msg;
   try
   {
    System.out.println("onMessage, recv text=" + tm.getText());
   }
   catch(Throwable t)
   {
    t.printStackTrace();
   }
  }
 }
 public void setupPTP() throws JMSException, [[NamingException|NamingException]]  {
  [[InitialContext|InitialContext]] iniCtx = new [[InitialContext|InitialContext]] );
  Object tmp = iniCtx.lookup( [[ConnectionFactory|ConnectionFactory]] );
  [[QueueConnectionFactory|QueueConnectionFactory]] qcf =  [[QueueConnectionFactory|QueueConnectionFactory]]  tmp;
  conn = qcf.createQueueConnection();
  que = (Queue) iniCtx.lookup("queue/testQueue");
  session = conn.createQueueSession(false,
  [[QueueSession|QueueSession]] AUTO_ACKNOWLEDGE);
  conn.start();
 }
 public void sendRecvAsync(String text) throws JMSException, [[NamingException|NamingException]]  {
  System.out.println("Begin sendRecvAsync");
  // Setup the PTP connection, session
  setupPTP();
  // Set the async listener
  [[QueueReceiver|QueueReceiver]] recv = session.createReceiver(que);
  recv.setMessageListener(new [[ExListener|ExListener]] ));
  [[QueueSender|QueueSender]] send = session.createSender(que);
  [[TextMessage|TextMessage]] tm = session.createTextMessage(text);
  send.send(tm);
  System.out.println("sendRecvAsync, sent text="+ tm.getText());
  send.close();
  System.out.println("End sendRecvAsync");
 }
 public void stop() throws JMSException
 {
  conn.stop(); 
  session.close();
  conn.close();
 }
 public static void main(String args[[]]) throws Exception
 {
  [[SendRecvClient|SendRecvClient]] client = new [[SendRecvClient|SendRecvClient]] );
  client.sendRecvAsync("A text msg");
  client.done.acquire();
  client.stop();
  System.exit(0);
 }
} /code Como las colas son creadas a traves de MBeans, se pueden administrar via la consola de administracion JMX

CMP / EJBs Container Managed Persistence #

Frameworks de persistencia Bruce Tate dijo: Creo que Hibernate está tremendamente de moda hoy en día, y probablemente siempre que hay que hablar sobre persistencia en algún forose comenzará con el. Hibernate, se ajusta a la realidad de las bases de datos relacionales mucho más que cualquier otro framework, y utiliza cosas como el SQL para su propio provecho. Yo recomiendo Hibernate para cualquier proyecto de pequeño y mediano tamaño. JDO tiene en el mercado quizás las mejores implementaciones técnicas. JDO es simple, efectivo, rápido y flexible. En el pasado, era una solución muy ligada a las bases de datos orientadas a objetos, pero he leido que 23 de las 27 implementaciones existentes, son productos relacionales. Quizás he visto que Kodo JDO de SolarMetric se coloca algo más en producción que cualquier otro framework. Yo recomiendo Kodo para implementaciones en clustering que requieran bastante potencia, o aquellas que requieran mapeos sofisticados. El detach model también está muy bien. Un poco de luz por tanto sobre Persitencia. Hay varios conceptos que conviene aclarar:
  • CMP (container manage persistence)
El contenedor en este caso el EJB lleva envevido el código de acceso a base de datos, (por medio de jdbc), hace uso de EJB query lenguaje para acceder a los datos.
  • BMP (bean manage persistence)
En este caso el los metodos del EJB hay que hacer la lógica de conexión a la base de datos. Por lo que permite utilizar DAO o JDO
  • JDO (Java Data Objects) (mapeo de clases a base de datos relacional) NADA QUE VER CON LO ANTERIOR. Esta fuera de los servidores de aplicaciones. Es persistencia de objetos.
Básicamente JDO es una implementación del patrón DAO de acceso a datos. JDO se puede comparar con los EJBs de entidad con persistencia manejada por el contenedor. Compararlos con los BMP no tiene mucho sentido ya que en BMP puedes utilizar también motores de persistencia. Algunas diferencias a grandes rasgos con EJB-CMP:
  • JDO es más ligero
  • JDO permite acceso a más fuentes de datos que EJB-CMP ( bases de datos orientadas a objetos por ejemplo )
  • JDO no requiere un servidor de aplicaciones
  • JDO no aprovecha los servicios de los servidores de aplicaciones automáticamente, por ejemplo clústers, balanceo de carga, etc.
  • JDO permite más flexibilidad en las consultas que EJB-CMP
  • ORM (Objeto-Relacional-mapping)
mapeador objeto-relacional. No necesita una estructura Java ee para existir. Simplemente tratan de salvar la inconpatibiliad entre la representación relacional de la base de datos y la representación jerárquica de la OO. Existen varios en el mercado dos de los mas maduros son Hibernate(jboss) y torque(apache) Un poco de luz Por un lado teníamos los EJB2.0 con su persistencia. Por el otro POJO'S (Los objetos java de toda la vida) con motores de persistencia (uno de ellos Hibernate). Sun vio que era bueno (lo de objetos persistentes sin necesidad de ser EJB), y se sacó JDO (Java Data Objects) para persistir POJO's fuera de un servidor de aplicaciones. Pero por otro lado la especificación EJB fue evolucionando (con el creador de Hibernate en el comité), haciendo que cada vez se parecerieran más a POJO's con anotaciones. Dentro de la nueva especificación EJB, la persistencia es a través de JPA (Java persistence API, que por debajo puede usar Hibernate o JDO). Lo "curioso" es que JPA también se puede usar fuera de un servidor de aplicaciones.Así que básicamente JPA y JDO se solapan (JPA sería el mecanismo de persistencia en JEE y JSE, y JDO sólo para objetos java normales), e Hibernate actualmente sería una implementación de JPA. (de un hilo de java hispano) En que circunstancias se debe elegir CMP frente a BMP+JDO o viceversa
  • Si el modelo de datos es complejo (relaciones) es mejor utilizar la implementación BMP
  • La mayoría de las implementaciones de CMP solo soportan bases de datos relacionales, por lo que si la base de datos no lo es, mejopr usar BMP
  • Si hay heterogeneidad en la capa de base de datos la automatización de CMP puede no ser una buena opción.

JTA Java Transaction API #

De la wikipedia: JTA (del inglés Java Transaction API - API para transacciones en Java) es parte de Java EE APIs, JTA establece una serie de Interfaces java entre el manejador de transacciones y las partes involucradas en el sistema de transacciones distribuidas: el servidor de aplicaciones, el manejador de recursos y las aplicaciones transaccionales JTA define un cpjnunto de interfaces estándares para regular la accione entre un servidore de transacciones y las partes que implicadas en el transaccion. Jboss tiene implementado las partes necesarias para poder realizar transacciones dentro de una arquitectura SOA
  • JBossJTA
  • JBossJTS (trasnaction service)

JAAS Java Authentication and Authorization Service #

tiene varios propositos:
  • autenticar los usuarios
  • controlar que pueden hacer y que no
  • estandarizar el modelo de seguridad dentro de la plataforma para poder controlar el acceso a los recursos.

Servlets/JSP #

Servlets #

Los Servlets son las respuesta de la tecnología Java a la programación CGI. Son programas que se ejecutan en un servidor Web y construyen páginas Web. Construir páginas Web Características:
  • Eficiencia
  • Son parte de la plataforma Java EE,
  • Portables entre los distintos contenedores
metodos principales de un servlet
  • doGet()
  • doPost()
  • service()
  • inti()
  • destroy()
Ciclo de vida de un servlet dentro de un contenedor de servlets sería (tener en cuenta que ciclo de vida de un componente esta controlado por su contenedor) Si se mappea un tipo de petición (url) a un servlet (web.xml) el contenedor responsable de dicho servlet realiza la siguientes acciones: 1. Si la instancia del servlet no existe en el contenedor: 1. Se carga la clase (servlet) 1. Se crea una instancia de dicha clase (esta instancia responderá a todas las peticiones que se hagan a la url mapeada) 1. Se inicializa la instancia, invocando al metodo initialize del servlet 1. Se invoca al metodo service (pasandole el request, response) cada vez que el contenedor recibe una petición que corresponde a la url mapeada en el web.xml 1. Si el contenedor necesita eliminar el servlet, (un-deploy), se hace invocando al metodo destroy. <img src="/image/image_gallery?img_id=12492&t=1206439990280" /> Ejemplo de servlet con metodo init: <pre> /* Java Programming with Oracle JDBC by Donald Bales ISBN: 059600088X Publisher: O'Reilly
  • /

import java.io.IOException; import java.io PrintWriter import java.sql.Connection; import java.sql DriverManager import java.sql ResultSet import java.sql.SQLException; import java.sql.Statement;

import javax.servlet ServletConfig import javax.servlet ServletException import javax.servlet UnavailableException import javax.servlet.http HttpServlet import javax.servlet.http HttpServletRequest import javax.servlet.http HttpServletResponse

public class TransactionConnectionServlet extends HttpServlet {

  public void init [[ServletConfig|ServletConfig]] config) throws [[ServletException|ServletException]] {
    super.init(config);
    try {
      // load the driver
      Class.forName("oracle.jdbc.driver [[OracleDriver|OracleDriver]] ).newInstance();
    } catch  [[ClassNotFoundException|ClassNotFoundException]] e) {
      throw new [[UnavailableException|UnavailableException]] 
           [[TransactionConnection|TransactionConnection]] init() [[ClassNotFoundException|ClassNotFoundException]]  "
              + e.getMessage());
    } catch  [[IllegalAccessException|IllegalAccessException]] e) {
      throw new [[UnavailableException|UnavailableException]] 
           [[TransactionConnection|TransactionConnection]] init() [[IllegalAccessException|IllegalAccessException]]  "
              + e.getMessage());
    } catch  [[InstantiationException|InstantiationException]] e) {
      throw new [[UnavailableException|UnavailableException]] 
           [[TransactionConnection|TransactionConnection]] init() [[InstantiationException|InstantiationException]]  "
              + e.getMessage());
    }
  }
  public void doGet [[HttpServletRequest|HttpServletRequest]] request, [[HttpServletResponse|HttpServletResponse]] response)
      throws IOException, [[ServletException|ServletException]] {
    response.setContentType("text/html");
    [[PrintWriter|PrintWriter]] out = response.getWriter();
    out.println("<html>");
    out.println("<head>");
    out.println("<title>A Per Transaction Connection</title>");
    out.println("</head>");
    out.println("<body>");
    Connection connection = null;
    try {
      // establish a connection
      connection = [[DriverManager|DriverManager]] getConnection(
          "jdbc:oracle:thin:@dssw2k01:1521:orcl", "scott", "tiger");
    } catch (SQLException e) {
      throw new [[UnavailableException|UnavailableException]] 
           [[TransactionConnection|TransactionConnection]] init() SQLException: "
              + e.getMessage());
    }
    Statement statement = null;
    [[ResultSet|ResultSet]] resultSet = null;
    String userName = null;
    try {
      // test the connection
      statement = connection.createStatement();
      resultSet = statement
          .executeQuery("select initcap(user) from sys.dual");
      if (resultSet.next())
        userName = resultSet.getString(1);
    } catch (SQLException e) {
      out.println( [[TransactionConnection|TransactionConnection]] doGet() SQLException: "
          + e.getMessage() + "<p>");
    } finally {
      if (resultSet != null)
        try {
          resultSet.close();
        } catch (SQLException ignore) {
        }
      if (statement != null)
        try {
          statement.close();
        } catch (SQLException ignore) {
        }
    }
    if (connection != null) {
      // close the connection
      try {
        connection.close();
      } catch (SQLException ignore) {
      }
    }
    out.println("Hello " + userName + "!<p>");
    out.println("You're using a per transaction connection!<p>");
    out.println("</body>");
    out.println("</html>");
  }
  public void doPost [[HttpServletRequest|HttpServletRequest]] request, [[HttpServletResponse|HttpServletResponse]] response)
      throws IOException, [[ServletException|ServletException]] {
    doGet(request, response);
  }
} </pre>

JSP #

Java Server Pages (JSP) es una tecnología que nos permite mezclar HTML estático con HTML generado dinámicamente. Muchas páginas Web que están construidas con programas CGI son casi estáticas, con la parte dinámica limitada a muy pocas localizaciones. Pero muchas variaciones CGI, incluyendo los servlets, hacen que generemos la página completa mediante nuestro programa, incluso aunque la mayoría de ella sea siempre lo mismo. JSP nos permite crear dos partes de forma separada. Aquí tenemos un ejemplo: code<!DOCTYPE HTML PUBLIC "-W3CDTD HTML 4.0 TransitionalEN"> <HTML> <HEAD><TITLE>Welcome to Our Store</TITLE></HEAD> <BODY> <H1>Welcome to Our Store</H1> <SMALL>Welcome, <!-- User name is "New User" for first-time visitors --> <% out.println(Utils.getUserNameFromCookie(request)); %> To access your account settings, click <A HREF="Account-Settings.html">here.</A></SMALL> <P> Regular HTML for all the rest of the on-line store's Web page. </BODY></HTML> /code Las jsp se utilizan para separar de la logica de presentación la presentación en si misma, deberían ser entendidas como plantillas que se rellenan con los datos que el servlet asociado decide que tienen que tener. No debería haber en ellos nada que no fuera parte de la presentación. Un jsp al final se convierte en tiempo de ejecución en un servlet.

EJBs #

Ya se ha definido en anteriores partes del documento lo que se entiende por EJB, vamos a pasar ahora a clasificar los tipos de EJBs y sus característticas principales.

Tipos de EJBs. #

Session EJBs Un Session EJB permite realizar cierta lógica solicitada por un cliente ya sea un JSP/Servlet, Applet e inclusive otro EJB. Existen dos tipos de Session EJB's: Stateless o Session EJB's:
  • Orientados a la conexión
  • Orientados a la petición respuesta
  • Los Stateless EJBs como su nombre indica no mantiene la sesion y se utilizan para realizar aquellas tareas que no requieren sesion
  • Los EJBs de session pueden alamcenar datos en la sesion que mantiene abierta con el cliente, y un tipico uso es hacer la lógica de negocio de por ejemplo un carrito de la compra.
<img src="/image/image_gallery?img_id=12476&t=1206439834075" /> 1. El cliente ya sea un "Servlet/JSP/Applet" o un simple programa Java de terminal busca la referencia del ejb en el arbol JNDI 1. Se envía el resultado hacia el Cliente indicando la ubicación del denominado EJB, una vez obtenida esta ubicación es posible generar el EJB. 1. El Cliente invoca el método create del Home Interface del EJB. 1. Posteriormente el "EJB Container" genera una instancia del EJB que fue llamado por el cliente. 1. Es necesario asociar la instancia generada con el Remote Interface del EJB , esto permite invocar "métodos/lógica de ejecución" sobre el EJB. 1. Se retornan los resultados de creación del EJB al Cliente. 1. Una vez confirmado que la instancia del EJB fue generada, el cliente puede invocar los respectivos métodos sobre el EJB. 1. A través del Remote Interface del EJB se invocan los respectivos métodos sobre la instancia del EJB. 1. Ejecutados los métodos sobre la instancia del EJB en cuestión, se retornan los resultados al cliente. Para ambientes distribuidos (cluster de máquinas), hay que hacer uso de los conceptos de Stubs y Skeletons, que es la forma como el cliente se entera de que métodos tiene publicados el EJB. La parte de publicacion la realiza en el lado del container el skeleton (haciendo uso de las interfaces, home y remote.) Messaging EJBs Un Messaging EJB aporta una capa de comunicación para entregar mensajes de forma asyncrona. Las características que hacen útiles los Messaginfg EJBs son:
  • Asyncronos
  • Aseguran la entrega (cola de mensajes)
  • No bloquean los procesos
Es decir "Asynchronous" o "non-blocking" 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 pérdida 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. Diferencias entre Session y Entity EJB's, "Point-to-Point" y "Publish/Subscribe".
  • Un "Messaging EJB" no utiliza ninguna interfase ("Home" o "Remote" ).
La razón por la cual no posee interfases es que un "Messaging Bean" simplemente procesa mensajes, los cuales no solamente pueden provenir de clientes Java (JSP/Servlets/Applet) sino también de un sistema messaging como los mencionados anteriormente; la segunda diferencia es:
  • Un "Messaging Bean" solo contiene un método de negocios llamado onMessage().
Esto se debe a que el "Messaging Bean" sólo consume mensajes, no ejecuta ningún tipo de lógica a diferencia de un "Session EJB" o "Entity EJB" que puede ejecutar diversas operaciones sobre determinada información; otra diferencia es:
  • Un "Messaging Bean" no posee ningún tipo de estado.
Existen dos metodos de comounicacion:
  • point-to-point el mensaje se entrega a en una cola de mensajes, se consume y desaparece
  • Publish/Subscribe (topic) se entrega el mensaje en un repositorio y durante un tiempo el mensaje se puede consultar
Entity EJBs Un Entity Bean a diferencia de un Session Bean trabaja en conjunción con un depósito de información (generalmente una Base de Datos), esto permite que el EJB manipule información residente en sistemas ajenos al "EJB Container"; en un Statefull (Session) EJB si ocurre una falla en el "EJB Container" se pierde toda información, mientras si se utiliza un Entity EJB aún permanecerá esta información en el sistema aledaño . En otras palabras, un Entity EJB manipula una copia | reflejo de información que reside en otro sistema. Al igual que Session EJB's existen dos tipos de Entity EJB's: (Entity) Bean Managed Persistence Este tipo de Entity Bean requiere que la lógica necesaria para accesar el sistema de información ( 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. (Entity) Container Managed Persistence Este Entity Bean como su nombre lo indica es manejado por el "EJB Container", a diferencia de un Bean Managed EJB donde se requiere definir lógica de acceso manualmente, en un Container Managed EJB el "EJB Container" genera toda lógica de acceso para el sistema de información ( Base de Datos ).

<img src="/image/image_gallery?img_id=12472&t=1206439791695" />

Existen dos tipos de "Entity EJB's" denominados "CMP (Container Managed Persistence)" y "BMP (Bean Managed Persistence)"

  • La diferencia entre ambos estriba en la manera en que se accesa la información residente en la Base de Datos.
En "BMP (Bean Managed Persistence)" es necesario escribir toda la lógica de acceso para la Base de Datos, esta lógica escrita a través del API JDBC implica contemplar diversos aspectos de codificación como parámetros, variables, algoritmos, y otros detalles más; si el EJB realiza interacciones complejas con la Base de Datos, este código no solo puede ser complejo de escribir sino difícil de mantener actualizado. En "CMP (Bean Managed Persistence)" la lógica de acceso hacia la Base de Datos es generada por el Application Server/"EJB Container", si bien suena como una maravilla, este mecanismo tiene sus desventajas comparado con un "BMP". El primer aspecto que es la ventaja de generar código automático es balanceado por la necesidad de contemplar y conocer a detalle configuraciones del Application Server requeridas para emplear "CMP"; la otra desventaja es que como el código es generado automáticamente no existe la posibilidad de afinarlo, el que sea generado código JDBC no implica que ha sido utilizado el mejor algoritmo para el trabajo.

Estructura de un EJB #

Un EJB esta compuesto de 4 partes (con la excepción de Messaging EJB's) las cuales son:
  • Bean Class
Es la parte del ejb que encierra la lógica de negocio, en esta parte se define el acceso a datos, las funciones matemáticas necesarias etc..
  • Home Interface
Interfaz que define un esqueleto para funciones utilizadas en el "Enterprise Bean Class", las funciones que deben ser declaradas en un "Home Interface" son aquellas necesarias para la creación-activación de un EJB, algunas de estas son: create, passivate, activate. Las funciones (metodos) creados al implementar este interfaz son las que deben tener un scope público, es decir son las que un cliente del EJB (Servlet, JSP otro EJB) debe invocar además solo deber encerrar la lógica de crearción/activación del EJB, la parte de lógica de negocio se debe implementar en el Remote Interface.
  • Remote Interface
Contiene las funciones públicas de la lógica de negocio
  • Deployment Descriptor
Es un archivo xml en el que se parametriza los valores del EJB
  • Nombre de base de datos
  • Usuarios que tiene acceso
  • ...
Además tambien se define en este archivo
  • Tipo de EJB
  • Modelo de Seguridad
  • Las funciones públicas del Remote interfaz

Ejemplo de código de un ejb de sesion #

Remote Interfaz: codepackage com.osmosislatina.ejb.intereses;

import javax.ejb.EJBObject; import java.rmi RemoteException

public interface Intereses extends EJBObject {

   public double calcularInteres(double capital, double tasa, double plazo)
       throws [[RemoteException|RemoteException]] 

} /code Home interfaz: codepackage com.osmosislatina.ejb.intereses;

import javax.ejb.EJBHome; import javax.ejb CreateException import java.rmi RemoteException

public interface InteresesHome extends EJBHome {

   Intereses create() throws [[RemoteException|RemoteException]]  [[CreateException|CreateException]]  

} /code El Ejb en si mismo codepackage com.osmosislatina.ejb.intereses;

import javax.ejb SessionBean import javax.ejb SessionContext

public class InteresesBean implements SessionBean {

      
   public double calcularInteres(double capital, double tasa, double plazo) { 
   
   System.out.println("Un Cliente llamo la función para calculo de Interés");
   return capital * Math.pow(1+tasa, plazo) - capital;
   }
   public [[InteresesBean|InteresesBean]] ) {}
   public void ejbCreate() {}
   public void ejbRemove() {}
   public void ejbPassivate() {}
   public void ejbActivate() {}
   public void setSessionContext [[SessionContext|SessionContext]] sc) {}
} /code

deployment descriptor ejb-jar.xml

code<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC

        "-//Sun Microsystems, Inc.//DTD Enterprise [[JavaBeans|JavaBeans]] 2.0//EN"
        "[http://java.sun.com/dtd/ejb-jar_2_0.dtd">]
 <ejb-jar>
      <description>Calculo de Intereses</description>
      <display-name>Calculo</display-name>
      <enterprise-beans>
        <session>
          <ejb-name>Calculo</ejb-name>
          <home>com.osmosislatina.ejb.intereses [[InteresesHome|InteresesHome]] /home>
          <remote>com.osmosislatina.ejb.intereses.Intereses</remote>
          <ejb-class>com.osmosislatina.ejb.intereses [[InteresesBean|InteresesBean]] /ejb-class>
          <session-type>Stateless</session-type>
          <transaction-type>Bean</transaction-type>
        </session>
      </enterprise-beans>
 </ejb-jar>
/code Cliente que hace uso del ejb: codepackage com.osmosislatina.ejb.intereses;

import java.util.Properties; import javax.rmi PortableRemoteObject import javax.naming.*;

class ClienteIntereses { public static void main(String[[]] args) { Properties env = new Properties(); // Definir las propiedades y ubicación de búsqueda de Nombres JNDI. env.setProperty("java.naming.factory.initial", "org.jnp.interfaces [[NamingContextFactory|NamingContextFactory]] ); env.setProperty("java.naming.provider.url", "localhost:1099"); env.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");

       try
       {
          // Traer el Contexto de Nombre 
          [[InitialContext|InitialContext]] jndiContext = new [[InitialContext|InitialContext]] env);
          System.out.println("Contexto Disponible");
          
          // Traer la Referencia del EJB
          Object ref  = jndiContext.lookup("Calculo");
          System.out.println("Se encontró Referencia del EJB!");
          
          // Traer la referencia del "Home Interface "
          [[InteresesHome|InteresesHome]] home =  [[InteresesHome|InteresesHome]]  
          [[PortableRemoteObject|PortableRemoteObject]] narrow (ref, [[InteresesHome|InteresesHome]] class);
          // Crear un Objeto  a partir del "Home Interface"
          Intereses interes = home.create();
          // Llamar la función 
          System.out.println("Interés de 10,000 Capital, a tasa 10%, 
                              bajo 2 plazos anuales:");
          System.out.println(interes.calcularInteres(10000, 0.10, 2));
       }
       catch(Exception e)
       {
          System.out.println(e.toString());
       }
    }
 }
/code

Contenedores de ejbs / Contenedores de servlets #

A la vista de todo lo anteriormente explicado queda claro que no es lo mismo un componente EJB que un componente tipo Servlet de un aplicativo war. Por lo tanto se puede tener contenedores de un tipo que no lo sean del otro. Es decir las especificaciones Java EE dicen que es como se tiene que comportar el contenedor con respecto al tipo de componentes que va albergar. Pero no dice si un servidro tiene que ser contenedor de servlets de ejbs o de servicios web. Por tanto se puede tener contenedores de servlets como el tomcat (que sirven para desplegar en ellos aplicacione war) pero no para desplegar EJBs o se puede disponer de un contenedor de EJBs como JBOSS que manejaría el ciclo de vidad de un EJB, pero por si solo no sería capaz de manejar un war. Por eso las distribuciones antiguas de JBOSS llevaban envevido un jetty y ahora llevan un apache-tomcat. JBoss es una implementación Open-Source de un "EJB Container"; es mediante este tipo de productos que es posible llevar acabo un desarrollo con EJB's "Enterprise Java Bean's" . Este tipo de producto ("EJB Container") generalmente no es distribuido como producto individual y por esta razón se le pudiera considerar a "JBoss" como un producto diferente mas no único: <img src="/image/image_gallery?img_id=12464&t=1206439726015" /> El producto JBoss es únicamente un EJB Container y es por esto que generalmente se utiliza en conjunción con un Web-Container, el Web-Container puede ser cualquiera disponible en el mercado, sin embargo, cuando obtenga JBoss incluirá Tomcat JBoss se utiliza con el Servlet Engine Tomcat estableciendo comunicación directa con JBoss como lo demuestra la linea roja punteada de la gráfica

Apendice I (Arquitectura SOA Service-Oriented Architecture) #

  • JBI Java Business Integration
  • WSDL Web service descripction language
  • ESB Enterprise service bus
<img src="/image/image_gallery?img_id=12488&t=1206439957643" />

Url de interés sobre los temas tratados #

<table border="1">
 <tr> <th>Descripción</td> <th>Url</td> </tr>
 <tr> <td> Breve turorial sobre j2ee orientado a desarrolladores, creación de un EJB y uso del interfaz JDBC</td> <td>[http://www.programacion.com/java/tutorial/j2ee] </td></tr>
 <tr> <td>Tutorial muy completo sobre j2ee especificaciones 1.4</td><td>[http://java.sun.com/j2ee/1.4/docs/tutorial/doc/</td></tr>]
 <tr> <td>Tutorial muy completo sobre j2ee especificaciones 1.5</td> <td>[http://java.sun.com/javaee/5/docs/tutorial/doc/</td>] </tr>
 <tr> <td>Introducción al JNDI </td> <td> [http://www.proactiva-calidad.com/java/jndi/introduccion.html]  </td> </tr>
 <tr> <td>Articulo sobre uso de JNDI </td> <td>[http://java.sun.com/developer/technicalArticles/Programming/jndi/index.html</td>] </tr>
 <tr> <td>Comparativa entre .NET y java EE</td> <td>[http://www.deltablog.com/2005/06/08/net-vs-j2ee/</td>] </tr>
 <tr> <td>Ciclo de vida de un servlet ejemplos de código etc..</td> <td>[http://www.oreilly.com/catalog/jservlet/chapter/ch03.html</td>] </tr>
 <tr> <td>Empaquetados .war</td> <td>[http://java.sun.com/javaee/5/docs/tutorial/doc/WebApp3.html</td>]
 <tr> <td>Empaquetados .ear</td> <td>[http://java.sun.com/javaee/5/docs/tutorial/doc/Overview7.html</td>] </tr>
 <tr> <td>Anotaciones / patron de inyección en java EE (jdk 1.5)</td> <td>[http://java.sun.com/developer/technicalArticles/J2EE/injection/</td></tr>]
 <tr> <td>Tecnologías en J2EE 1.5</td> <td>[http://java.sun.com/javaee/technologies/</td>] </tr>
 <tr> <td>Aproximación a una arquitectura SOA, EAI(enterprise application integration)</td> <td>[http://java.sun.com/developer/technicalArticles] [[WebServices|WebServices]] soa/</td> </tr>
 <tr> <td>Características de jdk 1.5</td> <td>[http://www.theserverside.com/tt/blogs/showblog.tss?id=JDK15</td>] </tr>
 <tr> <td>Patron de inyeccion de dependencias la plataforma ajva ee hace uso intensivo de este patron de diseño</td> <td>[http://www.theserverside.com/tt/articles/article.tss?l=IOCBeginners</td>] </tr>
 <tr> <td>Ejemplo de aplicacion que hace uso del patron de iOc inversion of control o inyeccion de dependencias</td> <td>[http://www.programacion.com/java/articulo/jap_injection/</td>] </tr>
 <tr> <td>Manual básico de instalación y configuracion de jboss</td> <td>[http://www.osmosislatina.com/jboss/</td></tr>]
 <tr> <td>Mini manuales sobre EJBs</td> <td>[http://javaejb.osmosislatina.com/</td>] </tr>
 <tr> <td>Tutorial sobre Servlets/jsp</td> <td>[http://www.programacion.com/java/tutorial/servlets_jsp/</td>]
 <tr> <td>JMX best parctices</td><td>[http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/best-practices.jsp</td></tr>]
 <tr> <td>Jboss JMXConsole</td> <td>[http://wiki.jboss.org/wiki/Wiki.jsp?page=JMXConsole</td>] </tr>
 <tr> <td>Herramientas open-source para el manejo del JMX</td> <td>[http://java-source.net/open-source/jmx</td>] </tr>
 <tr> <td>Implemetaciones opensource del estandar JMS</td> <td>[http://java-source.net/open-source/jms</td>]
 <tr> <td>Diferencias entre la aproximación CMP y BMP al problema de la persitencia</td> <td>[http://javaejb.osmosislatina.com/curso/cmp.htm</td>]
 <tr> <td>Articulo para desarrolladores sobre JDO</td> <td>[http://www.programacion.com/bbdd/articulo/jap_persis_jdo/</td></tr>]
 <tr> <td>JDO especificaciones, ejemplos etc...</td> <td>[http://java.sun.com/products/jdo/</td>] </tr>
 <tr> <td>Especificaciones de JTA</td> <td>[http://java.sun.com/products/jta/</td>] </tr>
 <tr> <td>JAAS overview</td> <td>[http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASRefGuide.html</td>] </tr>
</table>

Documentación #

<table border="1">
 <tr> <th>Descripción</th> <th>Documento</th> </tr>
 <tr> <td>Tutorial sobre javaEE, j2ee 1.5</td> <td>JavaEETutorial.pdf</td> </tr>
 <tr> <td>Breve presentación de la plataforma Java EE</td> <td [[JavaPlatform|JavaPlatform]] pdf</td> </tr>
 <tr> <td>Especificiones de la tecnologia servlet 2.4 por la jcp (java comunity process)</td> <td>servlet-2_4-fr-spec.pdf</td> </tr>
 <tr> <td>Tuning load test java ee</td> <td>HainesChapter6.pdf</td> </tr>
 <tr> <td>Test sobre escalabilidad de la plataforam java ee</td> <td>HainesChapter9.pdf</td> </tr>
</table>
  • 1 Vista de las distintas Capas-Tiers y los apis relacionados
  • 2 Esquema de la arquitectura jndi con todas sus capas/*
Promedio (0 Votos)
Comentarios