Full text
ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA INFORMÁTICA GRADO EN INGENIERÍA DE COMPUTADORES JAVA WEB COMMUNICATOR 2.0 Realizado por D. David Peláez Martín Tutorizado por Dr. Francisco Gutiérrez López Departamento Lenguajes y Ciencias de la Computación UNIVERSIDAD DE MÁLAGA MÁLAGA, Diciembre 2016 Fecha defensa: El Secretario del Tribunal
Resumen: El proyecto Java Web Communicator 2.0 consiste en el análisis, diseño e implementación una aplicación Web Java EE, basada en la tecnología JSF 2, que proporciona al usuario una interfaz web, que implementa un cliente de mensajería instantanea basada en el protocolo de mensajería XMPP (Extensible Messaging and Presence Protocol). Mediante la interfaz web el usuario puede establecer comunicación textual con los usuarios que tiene asociados. Asimismo, puede recibir mensajes de cualquiera de sus contactos en tiempo real. La interfaz web también permite conocer la disponibilidad de cada contacto en tiempo real. Los contactos del usuario podrán estar conectados al sistema utilizando la propia aplicación web desde otro navegador o también utilizando cualquier otra aplicación cliente XMPP. Algunos ejemplos de estas aplicaciones son: Empathy, Kopete o Jitsi. El servidor XMPP que tiene registrados los usuarios así como las relaciones entre ellos es Openfire 4.0.3 el cual sirve de fuente, tanto a la aplicación Web, como al resto de aplicaciones cliente XMPP. Para la comunicación de la aplicación Web con el servidor XMPP, se ha utilizado una librería de software libre denominada Smack 4.1.8 que proporciona una API para el uso de las funcionalidades del estándar XMPP. Palabras claves:XMPP, Java EE, JSF 2, Openfire, Chat, Java Web Communicator. Abstract: Java Web Communicator 2.0 project consist in the analysis, design and implementation of a Java EE Web application, based on JSF 2 technology which provides a web interface to the user that implements an instant message client based on the XMPP (Extensible Messaging and Presence Protocol). This web interface provides to the user the possibility of stablishing textual communication with other associated contacts in real time. The web inteface also provides real time information about the availability of every asocciated contact. Contacts can be connected to the system using the web application interface or any other third party XMPP clients such Empathy, Kopete or Jitsi. Openfire 4.0.3 is the XMPP server who manage the users and the relationship between them. Smack 4.1.8 is the API used for the web application to communicate with the XMPP server. It provides all the XMPP standard functionalities. Keywords: XMPP, Java EE, JSF 2, Openfire, Chat, Java Web Communicator.
Contenido 1. Introducción ......................................................................................................... 1 1.1. Objetivos ....................................................................................................... 1 1.2. Estado del arte .............................................................................................. 4 1.2.1. Mercado y protagonistas ......................................................................... 4 1.2.2. Oportunidades comerciales .................................................................... 6 1.2.3. El boom de la mensajería instantánea en España .................................. 7 2. Tecnologías ......................................................................................................... 9 2.1. Java ............................................................................................................... 9 2.1.1. Disponibilidad.......................................................................................... 9 2.1.2. Lenguaje simple ...................................................................................... 9 2.1.3. Distribuido ............................................................................................... 9 2.1.4. Robusto ................................................................................................ 10 2.1.5. Seguro .................................................................................................. 10 2.1.6. Indiferente a la arquitectura .................................................................. 10 2.1.7. Portable ................................................................................................ 10 2.1.8. Alto rendimiento ..................................................................................... 11 2.1.9. Dinámico ................................................................................................ 11 2.1.10. Produce Applets y Servlets ................................................................. 11 2.2. Java EE (Java Enterprise Edition) ................................................................ 11 2.3. JBoss AS ..................................................................................................... 16 2.4. JSF 2 ........................................................................................................... 16 2.5. Push ............................................................................................................ 21 2.6. AJAX ........................................................................................................... 21 2.7. XMPP (Extensible Messaging and Presence Protocol) ............................... 22 2.7.1. Openfire ................................................................................................ 23 2.7.2. Smack ................................................................................................... 24 2.8. Javascript .................................................................................................... 24 2.9. CSS (Cascading Style Sheets) .................................................................... 24 2.10. Log4j ........................................................................................................ 25 3. Arquitectura de la aplicación ............................................................................. 27 3.1. Diagrama de clases. .................................................................................... 29 3.1.1. El controlador LoginCtrl.class ............................................................... 29
3.1.2. El controlador ChatCtrl.class ................................................................ 30 3.1.3. Características generales de los controladores .................................... 30 3.1.4. Servicio XMPPService.class ................................................................. 31 3.2. Casos de uso .............................................................................................. 32 3.2.1. Autenticación ........................................................................................ 32 3.2.2. Acceso a pantalla de chat. .................................................................... 33 4. Manual de instalación ........................................................................................ 37 4.1. Guía de instalación de Openfire .................................................................. 39 4.2. Instalación de cliente de escritorio basado en XMPP .................................. 44 5. Conclusiones ..................................................................................................... 45 6. Líneas futuras .................................................................................................... 47 7. Bibliografía ........................................................................................................ 49
1 1. Introducción Las comunicaciones en la red son de gran importancia en la actualidad y por eso, las grandes empresas de comunicación proporcionan herramientas que permiten la comunicación mediante mensajería instantánea en tiempo real en Internet para cubrir esa necesidad global. La mensajería instantánea se identifica con las siglas IM por su traducción al inglés “Instant Messaging”. Este tipo de sistema de comunicación ha existido durante décadas en diversas formas, pero recientemente ha ganado bastante popularidad debido al crecimiento de Internet y la revolución de los dispositivos móviles. Mediante la mensajería instantánea se puede conversar con alguien que está geográficamente distante usando el ordenador. Cuando el usuario se registra, comienza creando una lista de personas con las que se está interesado en establecer comunicación en algún momento y que ya están registradas. Cuando alguna de estas personas se autentica en el sistema, aparecerá en la lista de contactos como disponible y el usuario ya podrá iniciar una conversación con esa persona. Normalmente se le enviarán una línea o dos y se esperará a la respuesta para volver a enviar otro mensaje corto. Se asemeja mucho a la conversación cara a cara entre dos personas. Una extensión de la mensajería instantánea es la introducción del concepto de grupo de conversación que consiste en que más de dos contactos comparten el mismo diálogo y cualquier de los contactos del grupo puede introducir texto en la zona común para que el resto de miembros del grupo la reciban. Este proyecto se puede considerar una versión adaptada a las nuevas tendencias y tecnologías del proyecto fin de carrera de la Ingeniería Técnica en Informática de Sistemas que realicé en 2004. Dicho proyecto se denominó Java Communicator e implementaba un sistema de mensajería instantánea utilizando la arquitectura cliente-servidor basada en sockets y realizada con tecnologías Java. 1.1. Objetivos En este proyecto se desarrolla el análisis, diseño e implementación de una aplicación Web Java EE que proporciona al usuario una interfaz web que le permite tener acceso a un sistema
8
9 2. Tecnologías 2.1. Java Es un lenguaje de programación que se engloba dentro del paradigma orientado a objetos. En la última versión de Java, la Java 8 se introduce el concepto de funciones lambda que hace que Java pase a englobarse también en los lenguajes de programación funcionales. A diferencia de otros lenguajes de programación, Java compila el código en un metalenguaje denominado Bytecode y requiere ser ejecutada en una JVM (Máquina Virtual Java) que es la propia de la arquitectura del sistema anfitrión y traduce el Bytecode a código máquina. Aunque no comenzó como un proyecto enfocado a Internet, Oracle ha sabido evolucionar para dar soporte a los requerimientos de las aplicaciones actuales. Todos los conceptos en los que se apoya el paradigma orientado a objetos, encapsulación, herencia, polimorfismo, etc., están presentes en Java. 2.1.1. Disponibilidad De un amplio conjunto de bibliotecas. Como ya se mencionó anteriormente, Java es algo más que un lenguaje. La programación de aplicaciones con Java se basa no solo en el empleo del juego de instrucciones que componen el lenguaje, sino, fundamentalmente, en la posibilidad de utilizar el amplísimo conjunto de clases que Oracle pone a disposición del programador y con las cuales es posible realizar prácticamente cualquier tipo de aplicación. 2.1.2. Lenguaje simple Java posee una curva de aprendizaje muy rápida. Resulta relativamente sencillo escribir Applets interesantes desde el principio. Todos aquellos familiarizados con C++ encontrarán que Java es más sencillo, ya que se han eliminado ciertas características, como los punteros. Debido a su semejanza con C y C++, y dado que la mayoría de la gente los conoce, aunque sea de forma elemental, resulta muy fácil aprender Java. Los programadores experimentados en C++ pueden migrar muy rápidamente a Java y ser productivos en poco tiempo. 2.1.3. Distribuido Java proporciona una colección de clases para su uso en aplicaciones de red, que permiten abrir sockets y establecer y aceptar conexiones con servidores o clientes remotos, facilitando así la creación de aplicaciones distribuidas. Interpretado y compilado a la vez. Java es compilado, en la medida en que su código fuente se transforma en una especie de código máquina, el Bytecode, semejantes a las instrucciones de ensamblador. Por otra parte, es interpretado, ya que el Bytecode se pueden ejecutar directamente sobre cualquier máquina a la cual se hayan portado el intérprete y el sistema de
10 ejecución en tiempo real (run-time). 2.1.4. Robusto Java fue diseñado para crear software altamente fiable. Para ello proporciona numerosas comprobaciones en compilación y en tiempo de ejecución. Sus características de memoria liberan a los programadores de una familia entera de errores (la aritmética de punteros), ya que se ha prescindido por completo de los punteros, y la recolección de basura elimina la necesidad de liberación explícita de memoria. 2.1.5. Seguro Java gestiona los errores y otros eventos, que se producen en tiempo de ejecución, mediante excepciones. En la programación siempre se producen errores, más o menos graves, pero que hay que gestionar y tratar correctamente. Por ello en Java proporciona un mecanismo consistente en el uso de bloques try/catch/finally. La técnica básica consiste en colocar las instrucciones que podrían provocar problemas dentro de un bloque try, y colocar a continuación uno o más bloques catch, de tal forma que si se provoca un error de un determinado tipo, lo que haremos será saltar al bloque catch capaz de gestionar ese tipo de error específico. El bloque catch contendrá el código necesario para gestionar ese tipo específico de error. Suponiendo que no se hubiesen provocado errores en el bloque try, nunca se ejecutarían los bloques catch. Si en la implementación de un método no se desea controlar los errores pero sí requerir al método que invoca a este método dicho control, se etiqueta el método donde se producen los errores con la palabra throws seguido del conjunto de excepciones que deberá controlar en el método llamante. Java proporciona una metodología muy potente para controlar errores en tiempo de ejecución. 2.1.6. Indiferente a la arquitectura Java está diseñado para soportar aplicaciones que serán ejecutadas en los más variados entornos de red, desde Unix a Windows, pasando por Mac y estaciones de trabajo, sobre arquitecturas distintas y con sistemas operativos diversos. Para acomodar requisitos de ejecución tan diversos o variopintos, el compilador de Java genera ByteCode: un formato intermedio indiferente a la arquitectura diseñado para transportar el código eficientemente a múltiples plataformas hardware y software. El resto de problemas los soluciona el intérprete de Java. 2.1.7. Portable La indiferencia a la arquitectura representa sólo una parte de su portabilidad. Además, Java especifica los tamaños de sus tipos de datos básicos y el comportamiento de sus operadores aritméticos, de manera que los programas son iguales en todas las plataformas. Estas dos últimas características se conocen como la Máquina Virtual Java (JVM).
11 2.1.8. Alto rendimiento Multihebra. Hoy en día ya se ven como terriblemente limitadas las aplicaciones que sólo pueden ejecutar una acción a la vez. Java soporta sincronización de múltiples hilos de ejecución (multithreading) a nivel de lenguaje, especialmente útiles en la creación de aplicaciones de red distribuidas. Así, mientras un hilo se encarga de la comunicación, otro puede interactuar con el usuario mientras otro presenta una animación en pantalla y otro realiza cálculos. 2.1.9. Dinámico El lenguaje Java y su sistema de ejecución en tiempo real son dinámicos en la fase de enlazado. Las clases sólo se enlazan a medida que son necesitadas. Se pueden enlazar nuevos módulos de código bajo demanda, procedente de fuentes muy variadas, incluso desde la Red. 2.1.10. Produce Applets y Servlets Java puede ser usado para crear tres tipos de programas: aplicaciones independientes, Applets y Servlets. Las aplicaciones independientes se comportan como cualquier otro programa escrito en cualquier lenguaje, como por ejemplo el navegador de Web HotJava, escrito íntegramente en Java. Por su parte, los Applets son pequeños programas que aparecen embebidos en las páginas Web, como aparecen los gráficos o el texto, pero con la capacidad de ejecutar acciones muy complejas, como animar imágenes, establecer conexiones de red, presentar menús y cuadros de diálogo para luego emprender acciones, etc. Finalmente, los Servlets, que son clases que proporcionan un servicio a través del protocolo HTTP. Los Servlets reciben peticiones desde un navegador Web, las procesan y devuelven una respuesta al navegador, normalmente HTML. Para realizar estas tareas pueden utilizar cualesquiera clases incluida en el lenguaje Java. Los Servlets requieren ser ejecutados en un Contenedor de Servlets. 2.2. Java EE (Java Enterprise Edition) Hace ya unos años, en 2013, fue publicada una nueva versión del conjunto de especificaciones que forman parte de Java EE con varias novedades y mejoras que aumentan la productividad. Java EE 7 es el conjunto de especificaciones a disposición de las aplicaciones empresariales que son implementadas por cada servidor de aplicaciones donde se ejecutan las aplicaciones Java, estas especificaciones describen la funcionalidad y permiten que una aplicación pueda ser ejecutada en cualquier servidor de aplicaciones Java que las implemente, ya sea WildFly, WebLogic o WebSphere, sin necesidad de grandes cambios o ninguno en absoluto al proporcionar interoperabilidad entre diferentes implementaciones con el objetivo de no estar encadenado a un determinado vendedor. Java EE usa como lenguaje de programación Java que incorporando numerosas novedades en la versión 8 lo hacen seguir siendo uno de los mejores lenguajes y más usado para el
12 desarrollo de aplicaciones empresariales. Estos cambios proporcionan muchas mejoras en el lenguaje Java en general. El modelo clásico de capas en la arquitectura de las aplicaciones Java EE se divide en las siguientes: Cliente: normalmente se trata de un navegador, pero puede ser un teléfono inteligente o una computadora de escritorio, incluso otra aplicación. Es la que presenta la información al usuario. Capa web: se comunica con el cliente y la capa de negocio. Obtiene los datos y los transforman al formato adecuado al cliente generalmente HTML o JSON. Capa de negocio: proporciona y persiste los datos de la capa cliente y contiene la lógica de negocio de la aplicación. Se ejecuta en un servidor de aplicaciones o contenedor de Servlets. Sistemas de información: donde se persisten los datos de la aplicación, puede ser una base de datos relacional como Oracle, MySQL o PostgreSQL o una base de datos NoSQL como Redis o MongoDB u otros sistemas como Elasticsearch. Figura 4. Aplicaciones multicapa Java EE En el listado de especificaciones encontramos algunas dedicadas a persistencia en base de datos (JDBC, JPA), transaccionalidad (JTA), procesamiento de peticiones HTTP (Servlets, JSF, REST), generación de HTML (Servlets, JSP, JSF), servicios web
13 basados en REST y SOAP (JAX-RS, JAX-WS), soporte para websockets en el lado del servidor y cliente, tratamiento de JSON, validación de objetos, comunicación entre aplicaciones desacoplada con mensajes (JMS), concurrencia, servicios de nombres y descubrimiento o trabajos en lotes entre otras. Las especificaciones y versiones que componen Java EE 7 son: Tecnologías aplicaciones Web (websockets, html) Java API for WebSocket 1.0 (nueva) Java API for JSON Processing 1.0 (nueva) Java Servlet 3.1 JavaServer Faces (JSF) 2.2 Expression Language (EL) 3.0 JavaServer Pages (JSP) 2.3 Tecnologías aplicaciones empresariales (persistencia, transaccionalidad, inyección de dependencias, concurrencia, validación, mensajería, correos electrónicos) Aplicaciones Batch para Java Platform 1.0 (nueva) Utilidades para concurrencia para Java EE 1.0 (nueva) Contextos e Injección de dependencias para Java (CDI) 1.1 Injección de dependencias para Java 1.0 Persistencia Java (JPA) 2.1 API para transacciones Java (JTA) 1.2 API de Servicio de Mensajes (JMS) 2.0 Enterprise JavaBeans (EJB) 3.2 Bean Validation 1.1 JavaMail 1.5 Interceptors 1.2 Java EE Connector Architecture (JCA) 1.7 Common Annotations for the Java Platform 1.2 Tecnologías servicios web (servicios web REST, SOAP) Java API for RESTful Web Services (JAX-RS) 2.0 Java API for XML-Based Web Services (JAX-WS) 2.2 Implementing Enterprise Web Services 1.3 Metadatos de servicios web para la plataforma Java Java API for XML-Based RPC (JAX-RPC) 1.1 (Opcional) Java API for XML Messaging 1.3 Java API for XML Registries (JAXR) 1.0
14 Tecnologías de gestión y seguridad (autenticación, autorización) Java Authentication Service Provider Interface for Containers (JASPIC) 1.1 Java Authorization Contract for Containers (JACC) 1.5 Java EE Application Deployment 1.2 (Opcional) J2EE Management 1.1 Suporte para Debug para otro lenguajes 1.0 Especificaciones relacionadas con Java EE en Java SE (bases de datos, XML, gestión) Java Database Connectivity (JDBC) 4.0 Java Architecture for XML Binding (JAXB) 2.2 Java Management Extensions (JMX) 2.0 JavaBeans Activation Framework (JAF) 1.1 Java API for XML Processing (JAXP) 1.3 Streaming API for XML (StAX) 1.0 Además de incorporar nuevas especificaciones y las existentes recibir mejoras entre las novedades se encuentran varias que facilitan el desarrollo posibilitando en gran medida prescindir de configuración en archivos XML propensos a errores, ya se inició en Java EE 6, sustituyéndose por definiciones declarativas con anotaciones. Entre las mejoras están: Usando la nueva funcionalidad de entrada y salida (NIO) de Java SE los Servlets pueden manejar comunicación asíncrona. Se permite upgrade del protocolo lo que permite por ejemplo empezar una petición como HTTP/1.1 y pasar a usar HTTP/2, en WildFly esto es usado para reducir el número de puertos abiertos. JPA ahora puede invocar procedimientos almacenados, ejecutar sentencias SQL de update y delete masivas y controlar que entidades son cargadas de forma ansiosa (eager) o vaga (lazy). Se continúa avanzando en lo iniciado en versiones anteriores permitiendo usar POJO con anotaciones para facilitar el desarrollo. JTA define una nueva anotación que permite a cualquier bean CDI usar transacciones. En JAX-RS se añade una API cliente para invocar enpoints REST, se añade soporte para E/S asíncrona tanto para el cliente como para el servidor y hypermedia linking. Bean Validation permite validación a nivel de método con mejor integración en el resto de la plataforma Java EE. Los servidores de aplicaciones Java pueden implementar todas las especificaciones
15 denominándose full-profile como JBoss/WildFly, WebLogic o WebSphere. Sin embargo, algunas aplicaciones no necesitan todas las funcionalidades definidas en Java EE por lo que algunos servidores como TomEE también WildFly pueden implementar únicamente un subconjunto para la generación de contenido web, denominándose así web-profile. Otros servidores como Tomcat y Jetty son contenedores de servlets que soportan un grupo más reducido de especificaciones de las tecnologías web (únicamente Servlet, JSP, EL y WebSocket) pero que siguen siendo suficientes para algunas aplicaciones o usando algunas equivalentes proporcionadas por Spring. Tecnologías web-profile Java Servlet API Enterprise Java Bean Lite Context and Dependency Injection Java Server Faces Java Transaction API Java Persistence API Web Socket Bean Validation JAX-RS JSON-P Java EE 7 fue publicada hace ya varios años y muy posiblemente muchas entidades públicas y empresas privadas seguirán usando versiones más antiguas para sus aplicaciones. En el mundo empresarial las aplicaciones se han de mantener funcionando algunos lustros o décadas, para atender este requisito Java en sus 20 años se ha caracterizado por ofrecer compatibilidad hacia atrás en cada nueva versión e incorporar en el lenguaje solo aquellas mejoras que se han mostrado útiles. Esto puede hacer parecer que avanza lentamente, al menos más que otras tecnologías, y que usando las versiones anteriores hoy parezcan obsoletas, en su momento XML era uno de los formatos más empleados para realizar configuración y se usaba profusamente, hoy se están prefiriendo formatos menos verbosos y legibles como JSON y YAML. Java 8 ofrece varias novedades en el lenguaje y Java EE 7 usando anotaciones en gran medida hace innecesarios los ficheros XML ambos siguiendo las nuevas tendencias del desarrollo y programación. Algunas personas comparan las tecnologías que prefieren con lo que recuerdan de versiones antiguas de Java o Java EE. Java EE ofrece a los desarrolladores un conjunto de especificaciones que cubren las necesidades de un gran número de aplicaciones empresariales y la plataforma ofrece garantías a largo plazo como ha demostrado que le hacen seguir siendo una de
16 opciones preferidas para el desarrollo. La alternativa a Java EE más usada es Spring y sus numerosos proyectos que proporcionan funcionalidades similares sin necesidad de un contenedor full-profile. En cualquiera de estas dos opciones la base de procesamiento y generación de HTML en el lado del servidor son los servlets pero estos trabajan a bajo nivel, no se suelen usar directamente prefiriéndose frameworks de más alto nivel como Spring MVC, Apache Tapestry, Grails, Struts u otros. Del mismo modo para el acceso a la base de datos está JDBC pero tampoco se suele usar directamente por ofrecer una API a bajo nivel prefiriendo Hibernate, JPA o jOOQ como alternativa a JDBC a los ORM anteriores. Bibliografía recomendada para un conocimiento más profundo sobre Java EE 7 son: Java EE 7, Java EE 7 Development with WildFly , Java EE 7 Developer Handbook, finalmente también es posible consultar el tutorial oficial de Java EE 7. El futuro Java EE 8 está planificado para 2017 fecha también planificada para Java 9 en la que se añadirá soporte para HTTP/2 y será la versión 4.0 de los Servlets. Pero no hace falta esperar hasta el 2017 para aprovecharnos hoy de las ventajas de HTTP/2 tanto para clientes como servidores, los principales navegadores ya lo soportan y se puede configurar HTTP/2 en varios servidores web y de aplicaciones Java como Nginx, Apache HTTPD, WildFly o Jetty. También se ha anunciado que como alternativa a JSF basado en componentes se proporcionará una especificación que implemente el patrón MVC basado en acciones. 2.3. JBoss AS Es un servidor de aplicaciones Java EE de código abierto implementado en Java puro. Al estar implementado en Java puede ser ejecutado en cualquier sistema operativo con el único requisito de que tenga la Máquina Virtual Java. Se estructura en distintos subsistemas que se activan en función de las necesidades de los componentes desplegados. De esta manera, implementa todas las funcionalidades exigidas para considerarse Servidor de Aplicaciones Java y no por ello tiene un tiempo de carga alto ni consume excesiva memoria en su ejecución. 2.4. JSF 2 JavaServer Faces es el framework oficial de Java Enterprise para el desarrollo de interfaces de usuario avanzadas en aplicaciones web. La especificación de JSF ha ido evolucionando desde su lanzamiento en 2004 y se ha ido consolidando, introduciendo nuevas características y funcionalidades. La especificación original de JavaServer Faces (1.0) se aprobó en marzo del 2004, con la Java Specification Request JSR 127. En esta especificación se define el
17 funcionamiento básico de JSF, introduciéndose sus características principales: uso de beans gestionados el lenguaje JSF EL, componentes básicos y navegación entre vistas. La especificación JavaServer Faces 1.2 se aprobó en mayo del 2006. La JSR donde se define es la JSR 252. En esta especificación se introducen algunas mejoras y correcciones en la especificación 1.1. Una de las principales es la introducción del lenguaje unificado de expresiones (Unified Expression Language o Unified EL ), que integra el lenguaje JSTL de expresiones de JSP y el lenguaje de expresiones de JSF en una única especificación. La especificación actual de JSF (Java Server Faces 2.2) se aprobó en mayo de 2013 (JSR 344) y la especificación de Java EE 7 se aprobó en 2015. En la especificación de la versión de JSF 2.1 se rompió definitivamente con JSP como forma de definir las vistas JSF y se introdujo un formato independiente de JSP. De hecho, la implementación de referencia de Oracle se integra con Facelets, un sistema de definición de plantillas para las páginas web que sustituye a JSP y que se ha popularizado con JSF 2.1. Algunas características importantes de esta especificación son: Soporte para AJAX. Componentes múltiples. Integración con Facelets. Gestión de recursos (hojas de estilo, imágenes, etc.) Facilidad de desarrollo y despliegue. JSF surge para dar soporte a las aplicaciones RIA (Rich Internet Applications) que son aplicaciones que ofrece una experiencia al usuario similar a la que ofrecen las aplicaciones de escritorio, como pueden ser: marcar posiciones en un mapa, imprimir, enviar ficheros, etc. JSF se basa en AJAX para ofrecer esa flexibilidad en las funcionalidades. La definición de la interfaz en JSF 2 se realiza en forma de páginas XHTML con distintos tipos de etiquetas. Estas páginas se denominan páginas JSF. La siguiente figura muestra el funcionamiento de JSF para generar una página por primera vez.
24 Favoritos. Autenticación vía Certificados, Kerbeos, LDAP, PAM y Radius. Almacenamiento en Active Directory, LDAP, MS SQL, MySQL, Oracle y PostgreSQL. SASL: ANONYMOUS, DIGEST-MD5 y Plain. 2.7.2. Smack Es una librería de software libre, multiplataforma, fácil de usar que implementa la API con las funciones de un cliente XMPP. Smack es una librería implementada completamente en Java y puede ser incluida en cualquier aplicación para implementar desde una simple integración con XMPP que envíe mensajes de notificación y detectores de disponibilidad e dispositivos hasta un cliente completo XMPP. En este proyecto se ha utilizado la versión 4.1.8. Cabe mencionar que, de la versión 3 a la versión 4, hubo un cambio considerable en la arquitectura de la librería que se basó en la utilización de la clase ThreadLocal para almacenar los manejadores de los distintos componentes como el gestor de Chat, el gestor de Presencia de los contactos, etc. 2.8. Javascript En términos generales, Javascript es un lenguaje interpretado en el navegador web, aunque hay librerías que se ejecutan en el servidor como Node.js. El funcionamiento de la aplicación tiene como requisito que el cliente tenga habilitado Javascript ya que, de forma implícita, JSF utiliza Javascript para realizar las llamadas AJAX al servidor y para la renderización parcial de la pantalla. También se ha utilizado de forma directa para evitar la incompatibilidad de los eventos Javascript originados por el framework Bootstrap y los eventos generados por JSF. 2.9. CSS (Cascading Style Sheets) Es un lenguaje de estilos utilizado para describir la presentación de un documento escrito en Markup Language (XML, LaTeX, troff) y su uso es más habitual en páginas XHTML y HTML. CSS ha evolucionado muchísimo desde su primera versión. La que más impacto tubo fue la versión 3, CSS3 y posteriormente se ha publicado la versión 4 que rompe con
25 los esquemas anterior y modulariza el lenguaje. En este proyecto se ha utilizado CSS para definir los estilos de las páginas. 2.10. Log4j Es una biblioteca código abierto desarrollada en Java por la Apache Software Foundation que permite a los desarrolladores de software escribir mensajes de registro, cuyo propósito es dejar constancia de una determinada transacción en tiempo de ejecución. Log4j permite filtrar los mensajes en función de su importancia. La configuración de salida y granularidad de los mensajes es realizada en tiempo de ejecución mediante el uso de archivos de configuración externos. En este proyecto se ha utilizado para escribir trazas en determinados puntos críticos del código.
26
27 3. Arquitectura de la aplicación En este proyecto se ha desarrollado una aplicación Web Java utilizando la arquitectura Modelo – Vista – Controlador. El proyecto se han integrado distintas tecnologías para crear la arquitectura. El backend implementa el servicio que incluye toda la interacción con el sistema XMPP. Esta capa de servicio implementa todos los métodos que utilizarán los controladores para la comunicación con el servidor XMPP. El frontend tiene una estructura particular acorde con la utilización requerida por la arquitectura JSF 2. Los controladores son las clases Managed Beans propias de JSF. La vista está formada por las páginas xhtml propias de JSF, así como por los recursos web estáticos: hojas de estilo (con extensión .css), ficheros Javascript (con extensión .js) e imágenes utilizadas en las páginas. Desde la página web correspondiente al chat se realiza toda la interacción relativa a la funcionalidad del intercambio de mensajes. Los controladores se han definido con ámbito Vista lo que hace que se mantenga la estructura de datos durante todo el tiempo que se permanezca en la misma página. El modelo de datos se actualiza en función de los eventos que realice el usuario mediante la interfaz web pero también se modificará de forma asíncrona cuando reciba mensajes de chat o de cambio de disponibilidad, desde sus contactos, a través de los listeners. Los listeners se ejecutan tras la autenticación en el sistema y reciben mensajes propios de XMPP. Para interacción con el servidor XMPP la capa de servicio hace uso de la API Java Smack 4.1.8. La API consta de diversas librerías Java y, en función de las operaciones y del tipo de aplicación, se requieren determinadas librerías. Por ejemplo, si se requiere utilizar la vCard, que es la tarjeta de datos de un contacto, se requiere la librería smack-extension. En el caso de esta aplicación, las librerías necesarias para interacción con XMPP son las siguientes:
28 Figura 7. Detalle librerías Smack. Las librerías necesarias para el uso de JSF 2.2 utilizando la implementación Mojarra 2.2 han sido las siguientes: Figura 8. Detalle librerías JSF. Se han utilizado funcionalidades que no se ofrecen en la distribución Mojarra 2.2, por esto, se ha requerido la utilización de Omnifaces. Para el uso de Omnifaces se ha requerido incluir la librería Omnifaces-2.5.1.jar Para la generación de trazas para hacer debug a distintos niveles de granularidad se ha utilizado la librería Log4j-1.2.17.jar .
29 3.1. Diagrama de clases. En el diagrama UML se pueden distinguir los dos controladores en la parte central. Lo controladores hacen uso de una instancia de la clase que implementa el servicio XMPP. 3.1.1. El controlador LoginCtrl.class Gestiona la autenticación y la desconexión. Para estas dos funciones utiliza la clase del modelo que almacena el usuario y la contraseña. Esta clase se denomina Figura 9. Diagrama de clases.
30 LoginVO.class. 3.1.2. El controlador ChatCtrl.class Gestiona todas las funciones que permiten mantener la conversación de mensajería instantánea con otro contacto, así como el estado de cada uno de los contactos del usuario. En el momento de la carga de la clase, se consultan los contactos del usuario, la disponibilidad de estos y la ficha con datos de cada contacto (vCard) esta ficha es opcional y contiene un fichero binario con la imagen del avatar del usuario, sus números de teléfono, direcciones físicas, dirección de correo electrónico, etc. En el diagrama UML se puede ver que ChatCtrl.class tiene una relación de cero a muchos ContactoInfoVO.class. Esta clase tiene los atributos de cada contacto, el estado de su disponibilidad y, a su vez, una relación de cero a muchos MensajeChatVO.class, implementada como una lista, que se corresponde con cada uno de los mensajes que se han intercambiado los dos contactos. Esta clase tiene las propiedades requeridas para almacenar el texto del mensaje, la hora y fecha de la creación del mensaje y si lo generó el contacto o el propio usuario. Cada vez que, por ejemplo, se añade un mensaje a lista, se invoca una instrucción para procesar el panel de mensajes y actualizar la pantalla del navegador de usuario. 3.1.3. Características generales de los controladores Se ha seguido la recomendación JSF de definir un controlador principal para cada vista. Estos controladores están definidos con ámbito de vista, por tanto, mantienen la estructura de datos instanciada durante todo el tiempo en el que el usuario se mantiene en la misma pantalla en la que se invocan. En el caso controlador chatCtrl, todos los contactos, el estado de cada uno y la estructura que almacena las conversaciones, las propiedades y los mensajes de estos, se actualiza dinámicamente y, los cambios, se reflejan la estructura representada en el navegador al usuario. Esta aplicación tiene como característica muy importante la posibilidad de actualización del modelo de datos que gestiona los datos por pantalla a partir de dos tipos de eventos. Eventos externos: recibidos a través de listeners que se activan a nivel de sesión HTTP y que atienden a mensajes que llegan del servidor XMPP de forma asíncrona.
31 La aplicación lanza, para cada usuario conectado, dos listeners que atenderán a mensajes procedentes del servidor XMPP, en el caso de este sistema, de Openfire: o Un listener atiende a cambios en: la disponibilidad de los contactos, la creación, eliminación o actualización de contactos. Cuando se crea o elimina un contacto, se elimina o se visualiza en la lista de contactos de la columna izquierda. Cuando cambia su estado de disponibilidad se modifica la imagen una marca de color que aparece junto al contacto. o Un segundo listener gestiona los mensajes de chat de cualquier contacto del usuario. Cuando se recibe un mensaje, si hay una ventana de conversación abierta, se añade el mensaje y, si no hay ventana creada, se genera y se introduce el nuevo mensaje. Para la actualización de la interfaz del navegador del usuario en tiempo real y de forma asíncrona se ha usado una tecnología de Push que permite enviar al navegador un mensaje asíncrono mediante a un canal al que se suscribe desde la página JSF. Para implementar la tecnología de Push se ha utilizado un componente de la librería de utilidades JSF denominada Omnifaces. De esta forma el listener, ejecutado en el servidor y asociado a la sesión de un usuario, recibe un mensaje. El mensaje es procesado por el controlador dando lugar a la actualización del modelo de datos. Posteriormente se envía un mensaje por el canal abierto desde la página para que se ejecute un evento que haga una petición al servidor para recoger así la nueva actualización del modelo de datos. Cuando se carga el controlador chatCtrl se inicializa la estructura de datos y se consultan los contactos, su estado y si tienen o no ficha de datos, en las que se incluye, imagen de avatar, teléfono, dirección y otros campos propios de cada contacto. 3.1.4. Servicio XMPPService.class Esta clase, como se puede ver en el diagrama de clases, se instancia desde cada uno de los controles para llamar a los distintos métodos que realizan las funciones de interacción con el servidor XMPP mediante la librería Smack. Esta clase está instanciada a nivel de sesión HTTP de manera que mantiene la instancia de la conexión al servidor XMPP durante toda la sesión. Esta conexión es compartida por todos los controladores mediante la injección de la clase XMPPService.
32 3.2. Casos de uso 3.2.1. Autenticación Figura 10. Pantalla de autenticación y desconexión. La pantalla de entrada inicio de la aplicación es la de autenticación. En la pantalla se presenta un formulario con dos campos de texto para introducir el usuario y contraseña del usuario para autenticar al usuario en el servidor XMPP donde, previamente debe estar registrado con un usuario y contraseña que deberá coincidir con el de entrada. En caso de autenticación no insatisfactoria se muestra “Usuario o contraseña incorrectos”. En caso de autenticación satisfactoria se muestra la pantalla de chat.
33 3.2.2. Acceso a pantalla de chat. Figura 11. Detalle de la pantalla de chat. En la pantalla de chat se muestran dos zonas muy diferenciadas. La columna izquierda, con fondo negro, en la que aparecen: El usuario autenticado en la sesión. Aparece en color naranja. Un listado con todos los contactos del usuario autenticado. Junto a cada contacto aparece un círculo que, si está conectado se mostrará en verde y, si no está conectado, aparecerá en rojo. Un botón con la opción de desconectar la sesión. 3.2.2.1. Abrir conversación con un contacto. Para abrir una conversación con un contacto, seleccionar el contacto de la lista de contactos. Esta opción solo estaría disponible para contactos conectados. No es posible abrir una ventana de conversación con un contacto no conectado. Los mensajes que envía el usuario aparecen en el lateral derecho y los mensajes escritos por el contacto, aparecen en el lateral izquierdo de la ventana de conversación.
40 3. Configuración de la base de datos donde se creará el esquema de datos de Openfire. Figura 18. Asistente configuración Openfire (opciones de Base de Datos). a. Se puede seleccionar utilizar una Sistema Gestor de Bases de Datos embebido o utilizar una conexión estándar a base de datos. En este caso he utilizado el SGBD MySQL. b. Para instalar MySQL Server se ejecuta en el terminal: sudo apt-get install mysql-server y en el script de instalación solicitará establecer la contraseña de root. c. Crear el esquema ‘openfire’ y el usuario ‘openfire’ con permisos DML y DDL sobre el esquema. d. Configuración de las credenciales en Openfire. En la captura se han introducido las credenciales para conectar como root pero es Figura 17. Asistente configuración Openfire (opciones de servidor).
41 aconsejable user un usuario específico que tenga acceso únicamente al esquema “openfire” Figura 19. Asistente de configuración Openfire (credenciales de Base de Datos). Figura 20. Asistente de configuración Openfire (Opciones de perfil). Carga de usuario y grupos en Openfire. En esta opción permite importar desde LDAP. Almacenar en Base de Datos solo la contraseña en hashes o almacenar los usuario y grupos en la base de datos. La última opción es la recomendada. 4. Establecer usuario y contraseña del usuario inicial que tendrá acceso a la herramienta de administración. En este caso se ha configurado admin/admin.
42 Figura 21. Asistente de configuración Openfire (cuenta de administrador). 5. Detalle de los puertos que habilita Openfire y la función de cada uno. Figura 22. Detalle de puertos y configuración. 6. Detalle de la configuración del final del servidor. Es importante destacar que el “Server Name” se debe especificar para identificar al contacto de un usuario cuando se realiza la inserción de los contactos.
43 7. Alta de usuarios. Para dar de alta usuarios acceder a la pestaña ‘Users/Groups’. Figura 24. Openfire, listado de usuarios. Figura 23. Openfire, descripción de detalles del servidor.
44 8. Para definir los contactos de un usuario, seleccionar el usuario y en el menú que aparece seleccionar la sección ‘Roster’. Para añadir a un contacto se debe registrar con su nombre de usuario seguido de ‘@’ y el nombre del ‘Server Name’ de Openfire. Figura 25. Openfire, listado de contactos. 9. Una vez insertado editar el contacto y modificar el modo de suscripción a ‘Both’. Esto hace que el servidor envíe mensajes al contacto con información del usuario y viceversa. La relación como ‘contacto’ debe estar definida en los Rosters de ambos usuarios. Debe ser bidireccional. 4.2. Instalación de cliente de escritorio basado en XMPP Un ejemplo de cliente de escritorio de mensajería instantánea basada en XMPP es Empathy. Para instalarlo en Ubuntu: sudo apt-get install empathy
45 5. Conclusiones Se ha desarrollado el proyecto cumpliendo los objetivos establecidos. Para crear el proyecto se ha realizado un estudio del arte de la tecnología XMPP en general y más en concreto del software libre que había disponible para realizar el proyecto. Se ha utilizado Openfire como servidor XMPP por ser un servidor flexible y de libre distribución. Se ha estudiado su funcionamiento, su estructura de datos, el proceso de instalación y configuración y parte de la administración: creando usuarios y relaciones entre ellos para desarrollar las pruebas de la aplicación web. Se podría haber utilizado el servidor público para test https://xmpp.net pero se ha optado por Openfire para adquirir más conocimientos y por ofrecer la posibilidad de instalarse en Intranets. También ofrece la posibilidad de sincronización con LDAP lo que permite ampliar este proyecto en el futuro. En este proyecto se planteaba como principal reto la integración de las distintas tecnologías necesarias para que una aplicación Web pueda servir interfaces de mensajería instantánea, que requieren actualización asíncrona, en un navegador web y hacer todo dependiente de la sesión HTTP. Cabe mencionar que ha resultado muy difícil encontrar ejemplos de uso de la API Smack 4 porque se ha realizado un cambio de arquitectura en el paso de versión de la 3 a la 4 y , aún no tiene un uso masivo debido a su reciente publicación. Los ejemplos existentes en la Web hacen referencia, en su mayoría a la versión 3. El proyecto se comenzó hace 2 años y la librería en se tenía basado el desarrollo era la versión 3. Se podría haber desarrollado todo el proyecto utilizando la versión 3 y una versión de Openfire inferior, para evitar incompatibilidades sobre la especificación de XMPP que implementan. Finalmente se ha optado por utilizar las últimas versiones de todos los componentes para que el sistema pueda ser ampliado en un futuro y también para que tarde más tiempo en quedar obsoleto. La integración de una tecnología como JSF, con un ciclo de vida muy complejo, de manera que los controladores instancien listeners a nivel de sesión y que a su vez, estos controladores mantengan una estructura de datos que permita disponer la información en pantalla y el hecho de utilizar una tecnología que, de forma asíncrona, actualice la interfaz del navegador en función de eventos asíncronos, ha sido muy satisfactorio aunque en muchas ocasiones se ha cuestionado su viabilidad.
46 Por otro lado, me ha resultado especialmente complejo el diseño web a partir de plantillas CSS modificadas y adaptadas a la funcionalidad implementada con JSF. El campo de las CSS y Javascript está evolucionando muy rápido y la curva de aprendizaje es bastante importante. En cuanto a CSS, en particular, la publicación de la especificación CSS4 y las técnicas como LESS y de los ficheros SCSS que permiten el anidamiento de las especificaciones de estilos, dan mucha complejidad y potencia a las hojas de estilo. En cuanto a Javascript, está evolucionando muy rápido en los últimos años, gracias a los motores de ejecución como Node.js, que le permiten sacarlo del entorno de ejecución de los navegadores y de frameworks como AngularJS, JQuery, etc. El trabajo como frontend developer en exclusiva está cada vez más justificado debido al grado de especialización que se requiere. La tendencia actualmente es el desarrollo de aplicaciones con el uso de microservicios en la parte del servidor y el resto de la ejecución se realiza en Javascript y tiene lugar en el navegador del usuario. El proyecto me ha permitido adquirir conocimientos sobre la tecnología JSF 2.2. El correcto uso de los Managed Beans es esencial para crear una arquitectura que, en el futuro reduzca el coste de mantenimiento. JSF ofrece soluciones para la gran cantidad de situaciones que surgen en la interacción con la aplicación desde un navegador Web. JSF hace uso de AJAX para mejorar la experiencia del usuario, pero es necesario comprender bien las fases del ciclo de vida de JSF para no tener problemas en la gestión de los eventos en el navegador. La librería Omnifaces ha facilitado la implementación por ofrecer utilidades que, por su evidente necesidad, muy probablemente, estarán incluidas en la próxima especificación de JSF. Entre las muchas utilidades que implementa, el componente para gestionar la tecnología Push, es muy bueno. Ofrece gran cantidad de modificadores para recoger la mayoría de las situaciones que se pueden presentar. Otra utilidad de Omnifaces de la que se ha hecho uso en la aplicación es la de la generación de una imagen gráfica en el cliente a partir de un flujo de bytes. Generalmente se requiere una request exclusiva para descargar el binario tras haber cargado la página. El componente GraphicImage de Omnifaces permite implementar esa funcionalidad de forma sencilla. La documentación de Omnifaces es muy explicativa y facilita mucho conocer el funcionamiento de los componentes que ofrece.
47 6. Líneas futuras La estructura de datos que se ha utilizado para gestionar los datos es muy robusta y escalable. Podrían incluirse muchas más funcionalidades a la aplicación con cambios mínimos en la estructura de datos. Algunas funcionalidades que se podrían añadir son: Registro de nuevos usuarios: alta de nuevo usuario en dos fases con envío de email para verificar autenticidad. Creación de relaciones entre usuarios: Implementar la funcionalidad permita a un usuario registrado buscar otros usuarios y enviarle una petición ‘petición de amistad’ que, si es confirmada, permita incluirlo como contacto. Gestionar el bloqueo temporal de usuarios. Establecer el estado de disponibilidad de forma personalizada. Cerrar ventanas de chat con un botón. Marcar en la columna de contactos el número de mensajes por contacto, que el usuario tiene pendiente de leer. Incluir la posibilidad de envío de pequeñas imágenes. Definir en la pantalla de autenticación los datos del servidor al que se desea conectar, para que, la misma interfaz permita conectarse a distintos dominios. Implementar soporte para conversaciones en grupo. Permitir ver la ficha de un usuario en una ventana. Permitir crear una ficha del usuario y almacenarla en el servidor. Guardando datos como: la imagen del avatar, teléfono, email, dirección postal, etc. Almacenar histórico de conversaciones para mostrarlas cuando se abre la ventana de chat de un contacto. De forma que permita continuarla. Entrega de mensajes en diferido. Cuando el contacto se conecta, recibirá todos los mensajes que sus contactos le hayan enviado mientras él estaba desconectado. En lugar de añadir funcionalidad, enfocar la aplicación a la gestión de elementos de Internet de las Cosas (IoT) de manera que los dispositivos envíen mensajes con el estado y el usuario, en lugar de tener contactos, sean dispositivos con sensores comunicando información.
48
49 7. Bibliografía Mastering Java Sever Faces 2.2 XMPP: HTTPs://XMPP.org/ Java EE 7 Java EE 7 Development with WildFly Java EE 7 Developer Handbook Tutorial oficial de Java EE 7. Especificación JSF 2. http://download.oracle.com/otndocs/jcp/jsf-2.0-fr-full-othJSpec/ Logj4 https://logging.apache.org/log4j/1.2/manual.html Omnifaces Push http://showcase.omnifaces.org/push/socket Descarga de imagen a partir de binario: http://showcase.omnifaces.org/components/graphicImage Instalación Openfire: http://download.igniterealtime.org/openfire/docs/latest/documentation/installguide.html Librería Smack: https://www.igniterealtime.org/projects/smack/documentation.jsp http://stackoverflow.com/