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
- 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
- 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)
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
- Capa de Web
- Capa de negocio
- Capa del sistema de información (base de datos)
- 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
- 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.
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
- deploy
<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
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.
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
- WebSphere http://www.ibm.com
- Geronimo http://geronimo.apache.org/
- Jboss http://www.jboss.com/
- Weblogic http://www.bea.com
- GlassFish https://glassfish.dev.java.net/
- 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 implementarJavaMail 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)
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 emailsJava Authentication and Authorization Service #
Define las especificaciones para que las aplicaciones Java EE sepan como deben hacer las autenticacionesEl 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
- Esto se suele hacer pero no es estandar
- publicar la conexión en el jndi
- recoger la conexión en la aplicación y utilizarala
- 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
<!-- 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
<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.
- 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)
- Standard MBean
- Dynamic MBean
- Model MBean
- Open MBean
- 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
- 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)
- BMP (bean manage persistence)
- 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.
- 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)
- 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
- doGet()
- doPost()
- service()
- inti()
- destroy()
- /
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.
- Asyncronos
- Aseguran la entrega (cola de mensajes)
- No bloquean los procesos
- Un "Messaging EJB" no utiliza ninguna interfase ("Home" o "Remote" ).
- Un "Messaging Bean" solo contiene un método de negocios llamado onMessage().
- Un "Messaging Bean" no posee ningún tipo de estado.
- 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
<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.
Estructura de un EJB #
Un EJB esta compuesto de 4 partes (con la excepción de Messaging EJB's) las cuales son:- Bean Class
- Home Interface
- Remote Interface
- Deployment Descriptor
- Nombre de base de datos
- Usuarios que tiene acceso
- ...
- 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áficaApendice I (Arquitectura SOA Service-Oriented Architecture) #
- JBI Java Business Integration
- WSDL Web service descripction language
- ESB Enterprise service bus
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/*