jueves, 31 de marzo de 2011

JEE5 - 1) Fundamentos

El presente artículo y los artículos relacionados (JEE) se basan en lo presentado en el libro Beginning Java EE5 (Editorial Apress), en los manuales y tutoriales de Sun/Oracle, y en problemas/soluciones propias.

La importancia de estudiar JEE, se encuentra desde mi punto de vista, en la gran cantidad de sistemas e infraestructuras actualmente implementadas, que requieren mantenimiento evolutivo y correctivo, y por supuesto, en la necesidad aún vigente de implementar nuevos sistemas usando JEE5.

JEE está enfocado en la creación de aplicaciones empresariales , las cuales se caracterizan por:
  • Resolver problemas empresariales, lo cual supone almacenamiento seguro, concurrencia, seguridad, escalabilidad, almacenamiento y procesamiento distrubuidos... “robustez en el plano de la complejidad”
  • Estar construidas sobre una infraestructura base: los servidores de aplicaciones. Haciendo una analogía con las obras civiles, cuando se construye un edificio no se fabrican ladrillos y vigas de acero, se utiliza las que provee algún fabricante y se usan elementos estrucuturales prefabricados en base a patrones adecuados, que permiten construir y a su vez conectar el nuevo edificio a infraestructuras que proveen servicios básicos. En el contexto del software, los servidores de aplicaciones proveen esos elementos e infraestructura base mediante contenedores, servicios y otros componentes, así como las facilidades de interacción respectivas.

Considerando lo anterior, se puede definir a JEE como:
  • Un conjunto de especificaciones para APIs.
  • Una arquitectura distrubuida y multicapa.
  • Definiciones para empaquetar componentes redistruibuibles para despliegue.
  • Un conjunto de componentes, contenedores y servicios estandarizados, para crear y desplegar aplicaciones distribuidas en la arquitectura mencionada.

La plataforma JEE define el estándar para desarrollar aplicaciones empresariales distribuidas basadas en componentes” (Sun Microsystems), y está fundada sobre J2SE. Así como J2SE cuenta con AWT/Swing para la construcción de sus interfaces gráficas de usuario, JEE provee un framework web basado en componentes para alcanzar el mismo fin: JavaServer Faces (JSF).
Arquitecturas multicapa
En general una aplicación puede estar constituida por 3 capas lógicas:
  • Capa de presentación
  • Capa de reglas del negocio o capa media
  • Capa de acceso a datos
Sistemas de una capa
  • Presentación, negocio y acceso a datos se encuentran en una sola capa computacional.
  • No soportan múltiples usuarios.
Sistemas cliente-servidor (dos capas)
  • Presentación y las reglas del negocio se encuentran en el cliente (DLLs, clases), el cual constituye la aplicación.
  • El manejo de datos lo realiza generalmente un servidor de bases de datos, que puede a su vez implementar cierta lógica (PL/SQL, Transact SQL, etc.)
  • El principal problema de esta arquitectura la actualización y gestión de cambios (distribuir una DLL, o cualquier otro componente, entre los n clientes para implementar 1 cambio o mejor).


Arquitectura convencional de dos capas, cliente-servidor (cliente pesado)
Arquitectura n capas
  • Se agrega una capa para implementar lo más crucial de la lógica del sistema, esta capa podría ser implementada en un servidor con gran capacidad de cómputo, mientras que la capa de presentación puede ser ligera, de forma que pueda ser ejecutada en un navegador.


Arquitectura base de tres capas
  • Se agrega una capa para implementar lo más crucial de la lógica del sistema, esta capa podría ser implementada en un servidor con gran capacidad de cómputo, mientras que la capa de presentación puede ser ligera, de forma que pueda ser ejecutada en un navegador.


Ejemplo de arquitectura de n capas
Problemas que atiende la arquitectura de n capas
Una arquitectura de n capas atiende 6 puntos clave:
  • Mantenibilidad: Se adapta a los cambios del negocio.
  • Consistencia: La lógica del negocio se implementa y se distribuye, lo cual previene implementaciones parciales inconsistentes entre múltiples aplicaciones.
  • Interoperabilidad: La arquitectura permite compartir/invocar servicios y datos entre aplicaciones.
  • Flexibilidad: La arquitectura no restringe la implementación de la presentación, la cual puede realizarse mediante GUIs, interfaces web, u otros tipos de interfaces.
  • Escalabilidad: Mediante la aplicación de la arquitectura y los patrones apropiados, una aplicación puede soportar una mayor carga de usuarios mediante cambios/ajustes en la infraestructura que la soporta.
  • Seguridad: Se pueden agregar mecanismos que mejoren la seguridad de las aplicaciones.

JEE se basa en los puntos explicados para una arquitectura de n capas, por ende los servidores de aplicaciones que implementan las especificación JEE, brindan la infraestructura y facilidades necesarias para construir robustas aplicaciones de n capas.

JEE procura independencia con el vendedor-proveedor de la infraestructura (servidor de aplicaciones), pero como especificación, no se ocupa ni del desempeño ni de la disponibilidad de las aplicaciones.
Características y conceptos de JEE
Clientes y servidores
Un cliente JEE puede ser implementado de diferentes maneras:
  • Clientes ligeros (thin), generalmente basados en web, que se ejecutan en un navegador, y bien pueden ser puro código HTML, o estar enriquecidos con JavaScript, o incluso ser applets.
  • Clientes pesados (fat), implementados mediante aplicaciones de consola, o GUIs con AWT/Swing. Este tipo de cliente está soportado por código Java que se ejecuta fuera del servidor.

Por otra parte, el servidor está conformado por dos tipos de componentes:
  • Componentes web (soportados por un contenedor web), que incluyen: JSPs y Servlets.
  • Componentes de negocio (soportados por un contenedor EJB), que son evidentemente componentes EJB.
Contenedores
Proveen un ambiente para los componentes descritos, así como las interfaces para que los componentes puedan acceder a la infraestructura del servidor (red, seguridad, manejo de transacciones, nombres, localización de recursos). JEE provee contenedores para Servlets, JSPs y EJBs.
Servlets.
  • Un servlet es un componente Java que implementa la interfaz javax.servlet.Servlet.
  • Aunque el modelo de Servlet es genérico, en JEE casi siempre se utilizan HTTPServlets.
  • Un servlet es invocado por una petición HTTP del cliente, que viene en forma de una consulta HTTP. El servidor web toma la petición y notifica al Contenedor Servlet, el cual carga el servlet e invoca el método apropiado de la interfaz javax.servlet.Servlet, la respuesta (un flujo) es devuelta por el servidor web al cliente.


Esquema básico de funcionamiento de un servlet
JSP
JSP es una tecnologia Java creada para generar dinámicamente contenido HTML, XML, o de otros tipos (tal como lo hace un servlet). De hecho, ¡JSP es un lenguaje de plantillas que permite generar un Servlet!

En primera instancia, una página JSP es un documento basado en HTML que puede incluir bloques de código Java, llamados scriptlets, que son introducidos mediante una sintaxis particular (<% código java %>), o pueden incluir etiquetas definidas en librerías de etiquetas (Tag Libraries) que son utilizadas para realizar acciones, tal como si se incluyera código Java; dichas etiquetas pueden ser personalizadas (tema que se revisará posteriormente). El propósito de las páginas JSP, podría decirse, es facilitar la construcción de las interfaces web de las aplicaciones a trabajadores que no necesariamente deben conocer los pormenores del lenguaje de programación Java, y que mas bien deben concentrarse en los detalles de la presentación (en vez de escribir servlets).

Cuando el servidor web recibe por primera vez una petición de una página JSP, se comunica con el contenedor JSP, el cual traduce la página JSP a código Java y lo compila en un servlet, el cual es cargado por el contenedor de servlets en la JVM del servidor en donde es instanciado recibiendo los parámetros del request del cliente. El servlet realiza los procesamientos necesarios y responde al servidor web, el cual canaliza dicha respuesta al cliente. Para las peticiones subsiguientes de la misma página JSP, siempre que ésta no haya sufrido cambios, el servidor web se refiere directamente al contenedor de servlets.

Debe acotarse en este punto que JEE enfatiza el uso de JSF, y que aunque para las especificaciones 1.1 y 1.2 de JSF el lenguaje de declaración de vista por defecto era JSP (basado en html), en JSF 2.0 el lenguaje de declaración de vista por defecto es Facelets (Sistema de plantillas web creado por Apache).
JSF
JSF es un framework web basado en componentes, que implementa el modelo MVC. Los componentes JSF facilitan la construcción de ricas interfaces web del lado del servidor, se conectan a fuentes de datos y beans, y conectan transparentemente eventos de cliente con manejadores en el servidor.
Cuando se usa JSF, toma un rol protagónico el servlet llamado FacesServlet, el cual se encarga de: procesar peticiones dirigidas a “vistas JSF”, cargar la plantilla apropiada para la vista requerida, construir un árbol de componentes para esa vista, procesar eventos y retornar la respuesta al cliente (por defecto HTML).
JDBC
Java DataBase Connectivity, es una API capaz de acceder a cualquier fuente tabular de datos, como por ejemplo, bases de datos relacionales. Para acceder transparentemente a las diferentes fuentes de datos que pueden haber, JDBC requiere de librerías específicas para cada sistema (drivers).
EJBs
Los EJBs son los componentes de negocio de una aplicación JEE. Como se mencionó, las aplicaciones empresariales son distribuidas, lo cual implica comunicaciones y servicios que pueden ser invocados de manera local y remota, lo cual en Java se puede conseguir con RMI (Remote method invocation).

El uso de RMI involucra 3 pasos:
  • Declarar una interfaz que extiende a javax.rmi.Remote
  • Implementar dicha interfaz con una clase que extienda a javax.rmi.server.UnicastRemoteObject
  • Instanciar la clase y registrarla mediante RMI Registry (un servicio de búsqueda simple)
Sin embargo, RMI tiene limitaciones en el contexto de las aplicaciones empresariales, lo cual da paso a los EJBs. RMI provee un framework base para comunicaciones que es utilizado por los contenedores EJB, los cuales mantienen separados a los EJBs de la capa de presentación, convirtiéndolos en un conjuto de servicios disponibles para una o más aplicaciones.

Un contenedor EJB realiza las siguientes tareas:
  • Cargar un EJB cuando es requerido.
  • Invoca al método apropiado según lo requerido.
  • Aplica reglas de seguridad.
  • Maneja la transaccionalidad de las operaciones.
Para desplegar un EJB en un contenedor EJB, se deben realizar pasos similares a los indicados para RMI:
  • Crear una interfaz local, o una interfaz remota, o ambas.
  • Implementar dichas interfaces mediante una clase (el EJB).
  • Desplegar el EJB en el contenedor.
Tipos de EJBs
Session Beans
Su propósito es proveer servicios de negocio (como retornar un conjunto de datos, o ejecutar un proceso), y a su vez se clasifican en Stateless Session Beans y Stateful Session Beans. Los session beans existen mientras dura la conversación o la sesión entre el cliente que hace la petición y el contenedor EJB. Los stateless session beans no guardan su estado, mientras que los stateful session beans lo pueden hacer en el ir y venir de requests/responses hasta que explícitamente se los descarte.
Entity beans
Su función es representar los objetos del negocio (entidades), los cuales pueden ser persistidos y recuperados del repositorio de datos mediante dos estrategias: delegando el control total al contenedor EJB (CMP – container managed persistence), o haciéndo “manualmente” (BMP – bean managed persistence).
Message-driven beans
Son especialmente útiles para atender procesos asíncronos. Los Message-driven beans (MDBs) proveen un modelo distinto del tradicional cliente-servidor, que consiste en servicios que escuchan a un Servicio de Mensajes (Message Service). Los servicios que escuchan (MDBs) son suscriptores de una cola, que es en donde se publican los mensajes respectivos.
Soporte XML en JEE
JEE provee un conjunto de APIs para trabajar con XML:
  • Java API for XML Processing (JAXP): provee funcionalidad para generar y procesar (parse) XML con DOM (Documment Object Model) y SAX (Simple API por XML).
  • Java API for XML Binding (JAXB): provee soporte para mapear XML desde y hacia clases Java.
  • Java API for XML Registries (JAXR): permite acceder a registros basados en XML, como UDDI (Universal Description, Discovery and Integration).
  • Java API for XML Messaging (JAXM): habilita comunicación vía XML y SOAP (Simple Object Access Protocol, para transmitir información entre web services).
  • Java API for XML-based Remote Procedure Calls (JAX-RPC): API avanzada para invocar procedimientos remotos.
Web Services
Un web service es “software para soportar la interacción máquina-máquina sobre una red. Su interfaz se describe con WSDL (Web Service Description Language) y se comunica con su cliente mediante SOAP” (el cliente necesita conocer el WSDL del web service para poder comunicarse).
Seguridad
JEE provee:
  • Acceso anónimo
  • Autenticación
  • Autorización
La seguridad en JEE puede ser declarativa (mediante descriptores – durante el despliegue de las aplicaciones) o programática (en tiempo de ejecución).
Arquitectuas JEE habituales
De las muchas variantes posibles, se presentan sólo dos, como casos ilustrativos:
Cliente servidor


Aplicación Web – EJB y/o EJB – Web Services

Sinópsis y siguientes temas
En el presente documento se han cubierto los conceptos y definiciones fundamentales de JEE, pasando por las arquitecturas relacionadas y los elementos constitutivos más importantes de la plataforma: Contenedores, servlets, JSPs, JSF, EJBs, web services y el soporte XML relacionado. Más adelante se revisarán las configuraciones básicas para empezar a construir aplicaciones web dentro del marco de JEE, así como los tópicos más importantes de JSP, con lo cual se conseguirá un sustento sólido para abordar JSF.

domingo, 27 de marzo de 2011

Leer un archivo de propiedades

Una tarea común es leer un archivo de propiedades desde una aplicación Java. Esto suele ser útil cuando se trata de configurar algún parámetro de la aplicación sin la necesidad de tener que compilarla cada vez, como por ejemplo cuando se trata de definir un Contexto Inicial para buscar componentes EJB desplegados en un servidor. Como IDE se utiliza Eclipse Galileo, sobre jdk1.5.0_22. Para empezar, se crea un proyecto nuevo, la perspectiva puede ser Java:



Las demás opciones se mantienen en sus valores por defecto. Una vez creado el proyecto, continuamos con el archivo de propiedades y la clase que lo leerá.

La clase:
package com.programmabilis.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Provee funcionalidades basicas para leer y procesar archivos
 
 @author Dustin Ghia
 
 */
public class UtilitarioArchivos {

    public static void main(String[] argumentos) {
        String archivo = "../../../archivo.properties";
        Properties props = new Properties();
        InputStream flujoEntrada = UtilitarioArchivos.class
                .getResourceAsStream(archivo);
        try {
            props.load(flujoEntrada);

            System.out.println("Nombres completos ---> "
                    "".concat(props.getProperty("prop1")).concat(" ").concat(
                            props.getProperty("prop2")));
        catch (IOException e) {
            e.printStackTrace();
        }
    }

}
Java2html

El archivo de propiedades:


prop1=
prop2=P\u00e1ez
Java2html

La vista del proyecto debe quedar aproximadamente así:


Nótese que se deben considerar la ubicación de la clase y la del archivo de propiedades para poder cargarlo. Finalmente, se enfatiza en que es posible obtener un campo con valor vacío del archivo de propiedades, aunque se podría asumir que se obtendría un null.