lunes, 15 de junio de 2009

Seam para el desarrollo de aplicaciones web empresariales en Java EE.

Es imposible hablar de Seam sin mencionar la herramienta seam-gen, que se ejecuta desde la línea de comando y es capaz de crear por nosotros de forma casi instantánea un proyecto totalmente funcional con la estructura de un proyecto Seam, los ficheros de configuración con versiones para entornos de producción y desarrollo, scripts de construcción, soporte total de Ajax mediante las librerías RichFaces o ICEFaces, vistas que utilizan Facelets como motor de plantillas, manejo del estado de la aplicación, soporte elemental de autenticación, autorización básica a nivel de página, manejo personalizado de errores y funcionalidades CRUD completas con las entidades, clases de acción, anotaciones para el manejo de la persistencia con las vistas para el manejo de estas de forma que se pueden interactuar tanto con sus datos específicos como aquellos que implican cambios en las relaciones que existen entre los objetos con relaciones de pertenencia a estas. Mediante el seam-gen podemos tomando como entrada una serie de pequeñas configuraciones sobre nombres de base datos, manejadores de conexión con orígenes de datos, tipo de librerías de presentación a utilizar, esquemas de base de datos existentes mediante ingeniería inversa y entidades con sus anotaciones de persistencia crear proyectos en blanco o totalmente funcionales y listos para desplegar en un entorno de producción o ser incluidos en un IDE(Eclipse, NetBeans y IntelliJIDEA), siendo adicionalmente posible obtener la estructura completa de la base de datos relacional generada a partir de las entidades persistentes. Esta herramienta es especialmente importante para usuarios que se están iniciando en el uso del Seam, de forma que pueden tener configurado un proyecto que se encuentra listo para soportar las necesidades más comunes de los usuarios y de este pueden tomar excelentes ideas desarrolladas por los autores de Seam y ver la forma en la que el framework debe usarse según con las directivas sobre las que fue creado. Resulta útil además para tener listo en pequeños periodos de tiempo prototipos para mostrar a superiores o clientes.



Las aplicaciones realizadas con Seam están pensadas para ser desplegadas en el JBoss Application Server, siendo este servidor el entorno más natural para las mismas aunque no el único posible. Teóricamente pueden ser desplegadas en cualquier servidor de aplicaciones que cumpla con la especificación Java EE, de forma certificada por la compañía JBoss los servidores de aplicación a utilizar con la versión 2.1.1 de Seam son: JBoss AS 4.2, IBM WebSphere 6.1, WebLogic 10, GlassFish 2, Oracle OC4J 11g y Tomcat en las versiones 5 y 6; aunque este último por su característica de ser un contenedor de servlets no compatible con Java EE se necesita sea extendido mediante el Embedded JBoss, permitiendo que éste funcione en la forma de un servidor de aplicaciones Java EE 5.

Anteriormente a Seam los desarrolladores muchas veces pasaban trabajo al momento de encontrar el lugar correcto donde almacenar datos referentes al caso de uso o funcionalidad a la que estaban dando cumplimiento, por lo que se veían obligados a almacenarlos en el contexto de sesión del usuario actual lo que trae problemas de concurrencia que eran de difícil de determinar en tiempo de desarrollo y que vienen aparejados con la posibilidad que existan usuarios trabajando en varias pestañas con una única aplicación. La solución a estas necesidades se encuentra en el nuevo modelo contextual que trae Seam con dos nuevos contextos más naturales para estos casos: conversación y proceso de negocio. La duración del contexto de conversación es añadida de forma declarativa y variando en el rango de una petición hasta una serie de ellas que terminan en la mayor parte de las ocasiones en un hito sobre un proceso de negocio, siendo Seam el encargado en todo momento de almacenar y mantener en un estado consistente los datos asociados a este contexto. Las conversaciones pueden ser anidadas o mantenerse varias de forma concurrente por parte de un mismo usuario como parte de una misma sesión de HTTP, siendo posible realizar cambios de un contexto conversacional a otro a través de mecanismo provistos por el framework. El contexto de proceso de negocio maneja y almacena los datos referentes a procesos de negocio de larga duración a través del motor de jBPM y puede contar con interacciones por parte de múltiples usuarios a través de un periodo extendido de tiempo. El contexto de proceso de negocio es de mayor duración incluso que el contexto de aplicación ya que es capaz de mantener el estado de los objetos entre paradas del servidor.

Por la importancia que involucra el manejo de la persistencia en el desarrollo de aplicaciones empresariales se le ha prestado especial atención en el Seam. Con el framework se provee soporte para las dos arquitecturas de persistencia más usadas: Hibernate 3 y JPA. Seam a través del manejo del estado evita que al utilizar estos mecanismos de persistencia los desarrolladores se encuentren con los antiguos fantasmas del pasado: LazyInitializationException y A Different Object with the same ID, vinculados a los modos de trabajo stateless fomentados por frameworks como Spring en donde el contexto persistente sólo se encuentra abierto en la duración de operación persistente o de la transacción, obligando luego a los desarrolladores a realizar merge sobre los objetos que se han obtenido de la base de datos en peticiones anteriores y que en ese momento se encuentran detachados, de forma que se pierden algunas ventajas como la realización automática del chequeo de objetos dirty en el contexto persistente y el primer nivel de caché para disminuir la cantidad de viajes a la base de datos. Se mejora la solución provista por el patrón Open Session in View en el manejo del contexto persistente, introduciendo el concepto de contexto persistente extendido, al permitir que el Persistence Manager pueda ser reutilizado en la duración de un caso de uso compuesto por varias peticiones al servidor vinculado al contexto de la conversación. Al usar JPA con Hibernate como proveedor se tiene acceso a las funcionalidades de este último que no se han incluido como parte de la especificación de JPA al no formar parte del estándar, siendo especialmente importante el manejo automático del flush de la sesión.
Un punto fuerte de Seam lo constituye el hecho de la gran cantidad de formas de configurar con que cuenta siendo cada una de ellas útil y recomendada en determinadas circunstancias, aunque se debe destacar que en muchas ocasiones se puede hacer de varias. La forma de configuración más poderosa es la configuración por omisión, mediante la que evitamos tener que configurar gran cantidad de elementos que configuran de forma automática a través de convenciones en los nombres utilizados en los componentes. La segunda es mediante anotaciones que cuentan con un amplio soporte y son especialmente fomentadas por los creadores del framework, siendo posible la declaración de componentes a través de las mismas y constituyen la única forma de realizar inyecciones dinámicas e eyecciones. La tercera y cuarta forma la constituyen las vías más convencionales, sirviéndose de los ampliamente usados archivos XML y de propiedades respectivamente.

Seam continúa con el concepto ampliamente conocido de inversión de control e inyección de dependencias aunque realizando aportes a los mismos para conseguir lo que se conoce como inversión absoluta del control o biyección, donde el framework es encargado tanto de inyectar las dependencias como de eyectar las referencias a variables de contexto que deben actualizadas una vez terminada una invocación. Se puede además marcar las diferencias entre las inyecciones estática y dinámica, en la primera la inyección ocurre en el momento en que se crea el componente y en la segunda sólo una vez que se realiza una invocación sobre el objeto, permitiendo de esta forma que puedan ser atados componentes de niveles menores de alcance a otros de mayor nivel como puede ser un componente de tipo petición a uno de tipo aplicación.

Mediante el modelo de comunicación entre componentes basado en eventos Seam es capaz de desacoplar de forma casi completa la interacción siempre necesaria entre los diferentes componentes de una aplicación para el cumplimiento de las metas planteadas, complementando así el mecanismo de inversión de control provisto por la biyección. Los eventos brindan a los componentes una vía sencilla de pasar mensajes de unos a otros. Seam proporciona el soporte para se puedan publicar mensajes desde invocaciones a métodos, como resultado de eventos relacionados con la navegación, como resultado de transiciones en los procesos de negocio generados por jBPM y eventos contextuales relacionados con el comportamiento interno del framework. La declaración puntos de lanzamiento de eventos puede ser realizada usando directamente el API, etiquetas en archivos de configuración y anotaciones. El recibo de estos eventos se realiza mediante un modelo de observadores tanto para eventos creados por el desarrollador así como los generados internamente por el framework.

El manejo de excepciones en Seam se realiza a través del modelo propuesto por el lenguaje de programación Java, donde se crean clases pertenecientes al árbol de herencia de la clase Exception y sus objetos son lanzados como resultado de la realización, generalmente con resultado fallido, de operaciones. Es posible además realizar anotaciones en algunas de estas clases, indicando que las excepciones pertenecientes a ésta son de aplicación y no de sistema, controlando de esta forma que no se haga un rollback sobre la transacción que se encuentre activa en el momento que sea lanzada una excepción de este tipo. El comportamiento en específico a aplicar al ocurrir una excepción es especificado a través de anotaciones o configuraciones en los archivos descriptores de páginas, aunque se debe decir que el comportamiento predeterminado en modo de desarrollo (a no ser que se desactive el modo debug de Seam) es mostrar la página debug de Seam, donde se muestra información detallada sobre la excepción ocurrida, el estado de las variables de contexto y el estado del árbol de componentes de JSF en el momento de ocurrir la misma. Esta página no sólo se encuentra accesible en el momento de ocurrir errores, en todo momento se puede acceder para tener información de las variables almacenadas en cada contexto y el estado de conversaciones y sesiones activas.

Seam brinda soporte de manera simple a las necesidades de los desarrolladores de tener el software probado antes de ser presentado a los clientes mediante pruebas de unidad e integración. Las pruebas de unidad son tan simples como realizar llamadas a objetos creados sin el manejo del contenedor, probándose de esta forma el componente en sí y no el modo en que interacciona con otros provistos por el framework. Las pruebas de integración se realizan dentro del anteriormente mencionado contenedor JBoss Embedded que maneja los componentes en la forma y con el acceso a los servicios que estos encontrarán en un entorno de producción, brindando la posibilidad de realizar pruebas reales sin las complicaciones y demoras que trae hacerlo dentro del contenedor haciendo uso de la clase SeamTest con la que se pueden manejar las necesidades de una aplicación realizada en este framework. El manejo de la infraestructura de pruebas es realizado de forma predeterminada a través de TestNG un novedoso framework para pruebas que puede ser configurado a través de anotaciones sin tener que atar nuestros componentes a clases o interfaces especificas, siendo posible su cambio por cualquier otro como jUnit.

En ocasiones resulta necesario contar con implementaciones mocks o falsas de los objetos para obtener de forma rápida cierto comportamiento sin influencias de componentes externos. En Seam es posible facilitar el trabajo con este escenario a través del soporte ofrecido por los niveles de prioridad posibles que puede tener un componente, determinando a los elementos que se usan en las pruebas altos niveles de prioridad como MOCK, por lo que al ser encuestados al contenedor y poseer el mismo nombre son entregados aquellos cuya prioridad es menor y cuando la aplicación se necesite desplegar en el ambiente de producción sin el comportamiento aportado por los objetos falsos, simplemente no se incluyen en los paquetes a desplegar.
Las tareas realizadas en conjunto por la librería Jboss EL y el Seam EL Resolver dan como resultado el surgimiento del Jboss EL, una extensión significativa al estándar Unified Expression Language (EL). Esta extensión da al desarrollador la posibilidad de realizar referencias a método y valores de componentes pasando parámetros como parte de la expresión, siendo posible también la llamada a métodos que no cumplan con la convención de nombres de Java. Es posible además la utilización de escuchadores de eventos de JSF que no tomen parámetros, de manera que se produce un cambio en la concepción en la forma en que se toman los datos referentes al evento ocurrido, evitando el desarrollo de la lógica ligada al API de JSF. De esta forma se hace opcional el uso de los conocidos parámetros de los tipos ActionEvent y ValueChangeEvent en este tipo de método. Este lenguaje de expresiones puede ser utilizado en gran cantidad de lugares dentro del Seam tales como: las definiciones de propiedades y comportamiento de objetos en la interfaz de usuario, cadenas de cualquier tipo dentro del código Java, archivos descriptores de páginas, consultas de Java Persistence Query Language (JPQL), definición de procesos de negocio y archivos de declaración de componentes, aumentando el valor de uso del mismo.

La seguridad de Seam está pensada como parte esencial del framework y por lo tanto es parte de su base y no una extensión de la que podemos o no disponer. En este modulo se ofrecen facilidades al desarrollador logrando que este no se sienta atemorizado por el uso del mismo, evitando las dificultades existentes en opciones disponibles anteriores para el manejo de seguridad para Java como JASS tedioso y primitivo así como Spring Security que hace al usuario caer en demasiada configuración a través de XML. Se puede realizar la autenticación contra una serie de proveedores de autenticación personalizables, permitiendo que se escoja el más apropiado a las necesidades de la aplicación. De esta forma se posibilita delegar la responsabilidad de la autenticación en servidores externos OpenID de la elección del usuario. Para la autorización se puede tomar entre dos modelos: autorización basada en roles (donde se compara el nombre del rol contra los contenidos por el usuario actual y con la que se pueden asegurar tanto vistas como componentes) y la autorización basada en reglas usando Drools, donde a través del uso de reglas dinámicas se hacen coincidir condiciones con hechos y cuando una de estas condiciones se cumple, es activada una regla y ejecutada una acción. Todo el modelo de seguridad es extensible por lo que es posible adicionar chequeos en el lugar que se desee como los comunes para determinar si el cliente que interactúa con el sistema es un humano o un sistema automatizado.

Actualmente en Seam son soportadas varias tecnologías para el manejo de las vistas como Wicket, Tapestry, GWT, Flex y JSF, siendo escogido este último como principal framework de presentación por las ventajas que este presenta en cuanto a la extensibilidad del ciclo de vida de las peticiones y su potente modelo de componentes de interfaz de usuario, aunque planea la inclusión de otros en un futuro. El motor de plantillas para JSF predeterminado y recomendado por los creadores de Seam es Facelets sobre otros más tradicionales como JSP, permitiendo la creación de páginas más simples y aumentar de forma considerable el rendimiento de la aplicación. Seam mejora significativamente a Jsf eliminando casi en la totalidad el XML de configuración y permitiendo el uso de POJOs y componentes manejados por EJB3 como beanes de respaldo usando anotaciones o configuraciones por omisión. Se pueden enlazar directamente campos de la vista con propiedades de las entidades de forma que la lógica relacionada con las validaciones se mantenga en éstas, así se evita que se una el comportamiento de las entidades con la forma en que se presentan. Toma la responsabilidad de erradicar el bache que dificultaba la unificación del modelo de programación estándar para la creación de aplicaciones seguras y escalables propuesto por EJB3 y los modelos de manejo de componentes y eventos del lado del servidor planteados por JSF.

Como complemento a JSF, Seam proporciona algunos componentes útiles en gran cantidad de aplicaciones, muchos de ellos facilitan el trabajo con conversaciones, procesos de negocio, etiquetas condicionales, controles de conversión para tipos básicos y enumerados, validación, presentación de elementos comunes de interfaz de usuario, entre otros. Es necesario resaltar además la inclusión de los controles de acción s:link y s:button, que están dirigidos a eliminar el siempre criticado comportamiento de los controles de acción de Jsf conocido como “todo es un Post”, permitiendo de esta forma la creación de vínculos que pueden ser almacenados como favoritos y la creación de aplicaciones stateless.

Mediante Seam podemos hacer frente a necesidades de creación otros tipos de presentación no pertenecientes al lenguaje de etiquetas HTML, permitiendo al desarrollador la generación de documentos pdf, hojas de cálculo de Microsoft Excel, gráficos, diagramas y archivos binarios a través de la integración del framework a componentes especializados en estos propósitos y el desarrollo de algunos propios. Es posible además la creación de páginas con requerimientos especiales en cuento al formato del texto presentado con el uso de Seam Text con la etiqueta s:formattedText cuyo uso es común en aplicaciones como foros y wikis, brindando además la posibilidad de adjuntar formatos a todo la aplicación o partes de ella con documentos CSS.

Para lograr la creación aplicaciones de la Web 2.0 utilizando Ajax en Seam se pueden utilizar las estrategias de la utilización librerías de componentes como las provistas por las librerías ICEFaces y RichFaces, la invocación de componentes del servidor desde el cliente usando JavaScript para llamadas remotas o una combinación de ambas. Usando código cliente es posible acceder a funcionalidades implementadas del lado del servidor mediante el mecanismo proporcionado por Seam para este escenario. Para la configuración de esta comunicación, del lado servidor sólo es necesaria la activación de un servlet encargado de escuchar las peticiones, mientras que en el cliente se incluyen dos librerías de JavaScript en la página donde se utilizará la funcionalidad y mediante una API provista por el framework es posible la obtención de componentes y la ejecución de acciones sobre los mismos conociendo el nombre de la variable de contexto. Mediante estas potencialidades y su integración con Ajax se alcanza una mayor experiencia de usuario al permitir la creación de interfaces más ricas.

Con Seam podemos utilizar un sistema de navegación más potente que el obtenido a través del uso de JSF: el flujo de navegación a nivel de vistas se puede definir de forma centralizada o individualmente para cada una de las vistas. En la toma de decisiones sobre a qué vista se navegará se tiene la posibilidad de realizar llamadas a métodos cualesquiera y no sólo métodos de acción, se pueden utilizar estructuras condicionales eligiendo navegar a una vista u otra así como utilizar JBoss EL para la obtención de valores de atributos y métodos. En las transiciones de página podemos realizar varias acciones que son de gran utilidad en disimiles escenarios para el desarrollador como: indicar puntos de inicio y terminación de conversaciones, controlar procesos de negocio, lanzar eventos, agregar mensajes de JSF y agregar parámetros a la petición que serán usados para continuar tareas que se entienden por más de una vista, utilizando un estilo stateless para evitar los problemas recurrentes relacionados con el uso de las funcionalidades de refrescar y regresar atrás de los navegadores. Para sobrepasar otra de las deficiencias de JSF en las definiciones de navegación, Seam brinda la posibilidad de configurar la ejecución de acciones que se realizarán cada vez que se realice la renderización de una vista no provocada por una acción del usuario sobre la misma página.
El uso de jBPM permite la definición de procesos de negocio mediante lenguajes de definición de procesos como Seam Page Flow, BPEL y jPDL. Sirve además como un motor para la ejecución de éstos. El motor de jBPM es el encargado de mantener, asegurar y persistir el estado de los procesos de negocio que se determina por los hitos cumplidos sobre los mismos y se representan por las tareas terminadas con éxito. Utilizando jBPM es posible lograr de forma simple el manejo de complejos flujos de trabajo, administración de tareas y trabajo colaborativo, permitiendo interacción de múltiples usuarios para dar cumplimiento a una única actividad. Es posible además la definición completa del flujo de navegación para la interfaz de usuario haciendo uso jPDL. Se logra de esta forma una mayor claridad en tiempo de diseño de los flujos a ejecutar para cada uno de los procesos y permite que el mismo se pueda revisar y diseñar de forma visual a través de una herramienta de modelado. Se posibilita la creación de flujos de navegación potentes donde para determinan la vista a navegar no sólo tiene en cuenta las acciones producidas en la vista anterior y los resultados aportados por éstas, sino además el flujo de páginas por el que se ha navegado y otros elementos del ambiente que puedan ser determinantes en la toma de una decisión.

Portlets 2.0 (JSR 206) es una tecnología que ha ganado adeptos en el mundo del desarrollo empresarial donde se le facilita al desarrollador la inclusión de varias aplicaciones que son presentadas en diferentes ventanas de la misma página. Sirviéndose de las ventajas aportadas por la especificación Portlet Bridge (JSR 301) es posible la integración a aplicaciones realizadas con Seam+JSF nuevas o existentes en ambientes de portales, más específicamente con Portlets 1.0 y 2.0. Con Portlet Bridge se maneja el ciclo de vida las peticiones JSF manteniendo la aplicación en su forma original. Sólo se hace necesario añadir 3 o 4 ficheros extras de configuración.

A través del Seam Application Framework se le entrega al desarrollador una serie de plantillas de componentes que pueden ser utilizadas en la creación de una gran variedad de sencillas aplicaciones web. Estas plantillas pueden ser utilizadas tanto a través de la extensión de clases Java como la configuración en archivos descriptores de componentes y brindan soporte para las operaciones de creación, lectura, actualización y eliminación de instancias de entidades, consultas de datos y el desarrollo de controladores de JSF.

CONCLUSIONES
Seam como framework de aplicaciones provee al usuario de una herramienta que facilita la aplicación de las mejores prácticas encontradas y documentadas por los desarrolladores a lo largo de las décadas. Integra el funcionamiento de varios componentes que se encuentran probados individualmente y sella los huecos que existían entre los mismos. Se evita la imposición de patrones o arquitecturas hecha por frameworks anteriores, dando la posibilidad al desarrollador de escoger la estructura de clases de su elección donde se puede prescindir de clases que anteriormente servían como puente entre las distintas capas de la aplicación. Seam permite el uso de los servicios de Java EE de forma ágil y proporciona herramientas en forma de extensiones e integración con componentes y librerías de terceros compatibles entre sí, haciendo el desarrollo de software más fácil y divertido.