¿Seam 2, 3 o JavaEE 6?
En la empresa para la que trabajo llevamos unos años utilizando el framework Seam 2 para nuestros desarrollos JavaEE. Por aquel entonces (2007, 2008...) era una decisión muy fácil del tomar: si querías un framework que te facilitara la vida sin salirte de la especificación JavaEE v5 Seam era una opción estupenda. Si los estándares no te importaban tanto podrías tirar por Spring 2.5, o alguno seguiría con Struts (1 ó 2).
En fin, Seam 2 ofrece un marco de trabajo completo e integrado, proporcionando una solución end to end para construir aplicaciones web reales, facilitándole la vida al programador al servir de "pegamento" entre los productos de la ensalada JavaEE (JPA, EJB, JSF, JTA, etc). De ahí su nombre (Seam, costura en inglés). Esto lo consigue gracias los siguientes principios rectores: la inyección de dependencias y la gestión de contextos. Siendo Seam un contenedor IoC es éste quien gobierna el ciclo de vida de los componentes que gestiona, por lo que puede mantener su estado entre todas esas capas de la arquitectura JavaEE que comentaba.
Seam 2 se creó para rellenar los huecos de JavaEE 5, pero hace ya tres años que se ha liberado la versión 6 de las especificaciones JavaEE, y también hace ya cierto tiempo que tenemos por ahí Seam 3, aunque con más pena que gloria.
A continuación haré una pequeña enumeración de las novedades que incorpora JavaEE 6, con comentarios sobre Seam 2:
CDI (Context and Dependency Injection - JSR 299)
Aunque JavaEE siempre ha tenido cierto nivel de inyección de dependencias gracias a los EJB, estos servicios se limitaban a aplicaciones completas (no simples aplicaciones web) en servidores pesados y a ciertos recursos. CDI proporciona estos servicios y más también en servidores de aplicaciones ligeros, servlet containers y aplicaciones JavaSE.
CDI es quizás la característica más novedosa que introduce JavaEE 6, curiosamente muy similar al mecanismo de inyección proporcionado por Seam 2, con leves toques de Spring y Google Guice.
De hecho fue Gavin King (creador de Hibernate y Seam) quien lideró el comité que definió CDI y fue Jboss quien llevó a cabo su implementación de referencia, Weld, que se distribuye desde la propia página oficial de Seam. De esta manera tampoco es de extrañar que JavaEE v6 introduzca los contextos existentes en Seam como Flash y Conversation, en añadidura a los clásicos contextos de Request, Session o Application. Por tanto los WebBeans de CDI son herencia de los componentes POJO de Seam.
Por otra parte CDI también ofrece un marco de desarrollo de extensiones modulares, que es precisamente la base de Seam 3.
Java Server Faces 2 (JSR 314)
Seam 2 está basado en JavaEE 5, lo que significa JSF 1.2. JavaEE 6 introduce JSF 2. Veamos las novedades que aporta JSF 2 sobre la versión 1.2 (nombraré solo algunas):
Plantillaje basado en Facelets: con JavaEE 6 Facelets pasa a formar parte del estándar. Esto ya estaba presente en las mejoras que Seam 2 aportaba a JSF 1.2.
Soporte para Ajax, mediante a la etiqueta estándar <f:ajax>, que es una estandarización del <a4j:support> presente en Seam 2 con Richfaces.
Soporte a parámetros GET: JSF 1.2 solo soportaba parámetros via POST, no obstante Seam 2 aportaba una gestión estupenda de los parámetros via GET, a mi modo de ver mejor que la que proporciona actualmente JSF 2. También nuevas etiquetas <h:link> y <h:button>, equivalentes a las <s:link> y <s:button> de Seam 2.
Validaciones: JSF 2 permite declarar validaciones a nivel de entities via annotations gracias a su integración con Bean Validations (JSR 303). Esto sin duda no es nada nuevo para los usuarios de Seam 2. No obstante JSF 2 permite validar campos vacíos, algo que era un infierno en JSF 1.2 y tampoco tiene una sencilla solución en Seam 2.
Nuevos scopes: el View scope, similar al Page scope de Seam 2, o el Flash scope, inspirado en las short running conversations de Seam 2, el truco para evitar las dolorosas Lazy Initializacion Exceptions, y para poder exponer un EJB directamente en la capa presentación.
Reglas de navegación más potentes y navegación condicional expresadas en el faces-config.xml, directamente inspiradas en las mejoras que Seam 2 proporciona a través del pages.xml.
Behaviors: permiten vincular scripts de cliente a componentes jsf para dotarlos de "comportamientos" específicos, con lo que se evita ensuciar los fuentes de la página con javascript, además de permitir la reutilización de estos "comportamientos". De hecho, <f:ajax>, del que hablé antes, es un ejemplo de implementación de behavior. Esto no tiene contrapartida en Seam 2.
Por tanto, a grandes rasgos JSF 2 ha servido para incluir en el estándar JSF muchas de las mejoras que proporcionaba Seam 2 a JSF 1.2.
Bean Validations (JSR 303)
Si bien ya lo he comentado por encima, las Bean Validations son una estandarización de los validadores de Hibernate. De hecho la implementación de referencia del JSR303 es Hibernate Validator. Nuevamente nos encontramos a los chicos de Seam e Hibernate promoviendo productos que acaban siendo incorporados al estándar JavaEE, y realizando sus implementaciones de referencia.
Ni que decir tiene que Seam 2 ya mejoraba JavaEE v5 permitiendo usar los validadores de hibernate a través de todas las capas del stack JavaEE, aplicando estas validaciones en medio del ciclo de validaciones de JSF. Gracias a esto si anotamos un campo de un entity con @Max(5000) y usamos ese entity en una página jsf el usuario recibe un mensaje de validación si mete 5001 en dicho campo.
JPA 2.0 (JSR 317)
Vemos que JPA continua incorporando funcionalidades de las últimas versiones de Hibernate. Estas son algunas mejoras con respecto a JPA 1.0:
Map Key Columns: mapeos relacionales que devuelve un Map en vez de una List, cuyas claves son las llaves extranjeras.
OneToMany unidireccional sin una join table
Bloqueo pesimista: JPA 1.0 solo permitía bloqueo optimista.
@OrderColumn: no confundir con @OrderBy. Ver diferencia.
Mejoras en el lenguaje de consulta (JPQL).
Introducción de la Criteria API: basado en Hibernate Criteria. Esto es muy beneficioso para la creación de consultas dinámicas, que en JPA 1.0 solo podían ser creadas manipulando la query JPQL como una String, algo sucio y muy sujeto a errores.
Control de cacheos, lo que permite ignorar copias en cache si hay sospecha de que la versión cacheada puede estar ya obsoleta.
Mejoras en el EntityManager, como el método evict, que permite desconectar una instancia de un entity de su contexto de persistencia, algo que antes solo se podía hacer recurriendo a métodos directos del provider JPA de turno, sacrificando la portabilidad del código.
EJB 3.1
Si bien con JavaEE 5 el modelo de EJB ya se había simplificado mucho, evitando el infierno de los descriptores XML, EJB 3.1 lo simplifica aun más.
Ya no es necesario crear un interface para acceder a un EJB local. La referencia al EJB se obtiene por inyección de dependencias. A nivel local ya casi no hay diferencia entre un EJB y un POJO gestionado por CDI, o un componente Seam.
Un nuevo tipo de EJB, Singleton Session Bean, que se suma a los otros dos session beans que había (stateless y statefull), algo que ya se podía hacer en Seam 2 con un componente de scope Application.
Invocaciones asíncronas a métodos
Nombres JNDI globales
Mejores TimerServices, ya nos podemos olvidar de Quartz.
Marco "light", llamado EJB Lite. Si el programador estima que no es necesaria toda la parafernalia que conlleva EJB puede optar por un subconjunto de funcionalidades, llamado EJB Lite, que se limita a permitir el uso de EJBs sin interfaz remoto, servicios de transaccionalidad, seguridad declarativa y programática, interceptores y descriptores de despliegue.
Ahora se pueden incluir EJBs dentro de un WAR en determinadas circunstancias. Ya no es necesario empaquetar la aplicación en un EAR, lo que implica poderse desplegar en un servlet container y no en un full blown application server.
En definitiva ya no resulta mucho más complicado construir una aplicación sobre EJBs que sobre simples POJOs.
No obstante una de las características de Seam 2 es su fuerte integración con EJB 3.0, que permite usar EJBs como sin fueran componentes Seam, instanciándolos con un @In o con un Component.getInstance(), así que el programador acostumbrado a Seam no notará gran alivio en EJB 3.1.
Servlet 3.0 (JSR 315)
También hay unas cuantas mejoras con respecto a la versión servlet 2.5 que incluía JavaEE v5:
Modularidad en el web.xml: cada componente que necesite configuración via web.xml puede incluir un web.xml modular en el META-INF/ de su jar.
Ahora se pueden cargar servlets y filters programáticamente en tiempo de ejecución.
Ya no es necesario declarar servlets en el web.xml. Cualquier clase que extienda HttpServlet y esté anotada con @WebServlet es registrada como un servlet por el contenedor durante el despliegue de la aplicación.
Servlets asíncronos que permiten comportamiento tipo Comet.
Así que tras haber revisado todos estos temas volvemos a la cuestión inicial:
¿Seam 2, 3 o JavaEE 6?
Leyendo las novedades que introduce JavaEE v6 alguien podría decir que los ingenieros del JCP cogieron Seam 2 y lo convirtieron en la nueva versión del estándar JavaEE. Son muchísimas las características de JavaEE v6 que ya existían de alguna manera en Seam 2. JavaEE 6 viene a ser en buena medida la incorporación al estándar de las mejoras que Seam 2 ofrecía sobre JavaEE 5. Por tanto parece que el programador de Seam 2 no se perderá mucho si sigue con Seam 2 en vez de pasar a JavaEE 6.
No obstante... ¿Qué pinta Seam 3 en todo esto? La verdad es que Seam 3 no se parece en mucho a Seam 2 ni en el fondo ni en la forma. Desde mi punto de vista el nombre no es muy afortunado.
¿Cual es la razón de ser de Seam 3? Dado JavaEE 6 ya cuenta con CDI como "core" Seam 3 se ha centrado en proporcionar módulos pluggables como CDI extensions. No obstante estos módulos no ofrecen una funcionalidad sólidamente integrada como hacía Seam 2, ya que están centrados en la portabilidad e independencia entre ellos. Por otra parte tampoco ofrecen aun todas las funcionalidades que aporta Seam 2, y algunos de ellos ni siquiera son estables.
Ver el sitio web oficial de Seam 3 da un poco de pena. Parece un pueblo fantasma. Aunque la versión 3.1 acaba de ser liberada no tiene pinta de que vaya a haber más. La documentación de Seam 3 es pobre, no hay ningún libro sobre él y se encuentran muy pocos recursos en internet.
Parece ser que después de mucho debate interno el equipo de Seam ha decidido centrar sus esfuerzos en un desarrollo independiente, sin el liderazgo de JBoss, llamado Apache DeltaSpike, que al igual que Seam 3 es una colección de extensiones CDI.
Por tanto Seam 3 no parece tener un futuro nada claro, y no creo que DeltaSpike esté lo suficientemente maduro ni que tenga aun la suficiente implantación como para comprometerse con él.
Pero por suerte Seam 2 sigue en desarrollo activo. Su versión 2.3 acaba de lanzar su Beta2 hace apenas tres de meses. ¿Qué hay de nuevo en Seam 2.3?
Lo más importante es que se adapta a JSF 2.0
Se abandona el modelo de distribución y construcción basado en ANT en favor de MAVEN 3
Compatibilidad con RichFaces 4, Hibernate 4, Spring 3.1
Podrá ejecutarse en JBoss AS 7.1, es decir, un servidor certificado JavaEE 6, lo que conllevará todos los beneficios de la versión 6 de JavaEE (JPA 2.0, EJB 3.1, Servlet 3.0, etc).
Recordemos que JBoss AS 7.1 incorpora el WebProfile (una versión ligera de servidor JavaEE pensada para aplicaciones web) que permite tiempos de reinicio espectaculares y con bajo consumo de recursos.
Conclusión
Creo que podemos descartar aventuras con Seam 3 o DeltaSpike por ahora. Habrá que ver cómo evolucionan.
Definitivamente creo que JavaEE 6 ha alcanzado un nivel que permite desarrollar aplicaciones empresariales con la productividad suficiente como para prescindir de frameworks de terceros, y el consecuente riesgo de "vendor lockin" que ello conlleva.
No obstante creo que Seam 2 sigue ofreciendo una experiencia más integrada y completa que JavaEE 6 para desarrollos rápidos y sistemas ligeros.
----
Algunas fuentes:
http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2
http://en.wikibooks.org/wiki/Java_Persistence/What_is_new_in_JPA_2.0%3F
http://www.dosideas.com/noticias/java/528-ejb-31-un-paso-importante-hacia-la-madurez.html
http://www.oracle.com/technetwork/server-storage/ts-5415-159162.pdf
http://www.bpm-guide.de/2011/09/14/move-to-java-ee-6/






