
Nuestro viaje comienza explorando el motivo que lo justifica: las especificaciones estándar de Java que conforman Jakarta EE. Veamos en qué consisten y cómo se desarrollan antes de emplearlas en un primer proyecto.
El mundo de las especificaciones Java
El DRAE (Diccionario de la Real Academia) define especificación como <<información proporcionada por el fabricante de un producto, la cual describe sus componentes, características y funcionamiento>>. Esta definición se ajusta bien al contexto técnico en el que vamos a usar la palabra.
Una especificación propone las funcionalidades y componentes que debería tener una librería Java -el producto- que aspire a satisfacer una necesidad habitual muy abstracta: la creación de servicios REST, el acceso a base de datos, la comunicación con websockets, etc. El uso del verbo proponer no es casual pues la especificación es un estándar público. Los productos que lo sigan son creados por terceros -proveedores o vendors– según su visión particular y sin pagar regalías o licencias.
No hace falta salir de Java para encontrar un buen símil. Pensemos en una especificación como si fuera una interfaz y su documentación. Un ente abstracto que no cobra vida hasta que una clase codifique sus operaciones. Cómo lo haga es irrelevante para el cliente de la interfaz en lo que respecta al uso. Lo importante es que verifique el comportamiento descrito por la documentación y podamos usarla con los métodos de la interfaz.
Siendo rigurosos, una especificación en un conjunto formado por tres elementos.
- Artefactos de software. Contienen el código con la API que permite utilizar la especificación, prolijo en comentarios javadoc. Está compuesto en su mayor parte por interfaces y anotaciones. También encontraremos enumerados, excepciones y alguna que otra clase de otro tipo.
- El documento en el que se definen las funcionalidades y cómo se usan. Suele ser detallado y claro.
- Un conjunto de pruebas automáticas denominado kit de compatibilidad tecnológica (TCK, Technology Compatibility Kit). Su finalidad es la verificación objetiva y fiable de que un producto cumple el estándar.
La siguiente figura muestra las relaciones entre los tres componentes anteriores, una aplicación y las implementaciones compatibles. La aplicación hace uso de la API, el único código que proporciona el estándar, y tenemos que seleccionar un producto que provea sus servicios y operaciones. Estos son representados por el conjunto de cajitas dentro del bloque verde y, atención, nos sirve cualquiera desde el punto de vista de las funcionalidades (otro asunto es que unas sean más eficientes que otras o que cuenten con soporte comercial, por ejemplo). De este modo, disfrutamos de los beneficios de trabajar con estándares abiertos: la libertad de elección entre múltiples proveedores. Y si la mayoría de productos disponibles en el mercado son libres y gratuitos, como es el caso, mejor todavía.

Las especificaciones suelen ser sencillas -es uno de sus objetivos- y las implementaciones compatibles tienden a ampliarlas con sus propias funcionalidades. Mientras la aplicación solo utilice la API del estándar, las implementaciones se pueden intercambiar sin problema alguno. Pero la compatibilidad se irá al traste si recurrimos a características exclusivas de una de ellas. Esto no es necesariamente negativo aunque debemos tenerlo en cuenta. Un ejemplo paradigmático es Hibernate ORM, producto compatible con Jakarta Persistence. Tiene funcionalidades propias tan interesantes y útiles que les dedicaré un capítulo.
De JEE a Jakarta EE
El desarrollo de JEE y, por extensión, de las especificaciones que abarca, era -nótese el tiempo verbal- controlado por Oracle y realizado según los procedimientos establecidos por el programa Java Community Process (JCP) a partir de lo que se conoce como Java Specification Request (JSR). Una JSR es una solicitud formal que plantea una especificación nueva o la modificación de alguna ya existente.
Siguiendo el estricto flujo de trabajo definido por el JCP, una JSR se convierte en una especificación tras ser aprobada por los miembros del comité ejecutivo del JCP, compuesto por empresas, organizaciones y profesionales a título individual. Por ejemplo, JPA 2.2 se corresponde con la JSR-338. Se suele utilizar la primera denominación por ser más fácil de recordar.
A finales de 2017, Oracle, como parte de sus acciones para liberar Java, cedió todas las especificaciones a la fundación Eclipse. JEE pasó a formar parte de la iniciativa Eclipse Enterprise for Java (EE4J), donde continúa su desarrollo con un nuevo flujo de trabajo ágil y abierto denominado Jakarta Specification Process (JESP).
Debido a cuestiones legales en el uso de la marca Java, propiedad de Oracle, las especificaciones han cambiado en su nombre la palabra Java por la denominación genérica Jakarta. Esta marca ha sido gentilmente cedida por la Fundación Apache quien la usaba hace muchos años para englobar sus proyectos de código abierto desarrollados con Java. Así pues, el sucesor de Java EE\JEE se ha bautizado como Jakarta EE.
Hemos apuntado en la sección anterior que para usar una especificación se requiere un producto compatible. De hecho, en JEE todas deben tener una implementación de referencia a modo de ejemplo. Esta exigencia ha desaparecido del JESP y ahora se habla de implementaciones compatibles, denominación que pueden ostentar aquellos productos que pasen con éxito las pruebas definidas por el TCK de la especificación que afirman implementar y sin pasar por un farragoso proceso de certificación.
Volviendo a la historia de JEE, su última versión fue la octava (septiembre 2017), y desde ahí damos el salto a Jakarta EE 8. Resulta elocuente que se haya mantenido el número de versión: no hay novedad alguna más allá del simple cambio del nombre y el debut del proceso JESP. Las primeras modificaciones de cierto calado llegaron en noviembre de 2020 con la publicación de Jakarta EE 9, la que puede ser considerada como la «primera» entrega de Jakarta EE.
La siguiente línea temporal muestra los grandes hitos recientes de JEE\Jakarta EE y Java.

Jakarta EE 9
En este lanzamiento no hay cambios en las definiciones de las APIs. Su objetivo es sentar las bases para facilitar el desarrollo de nuevas versiones, dejando atrás JEE y cualquier lastre que pudiera comprometer el rápido progreso y la innovación de la plataforma.
Estas son las novedades más significativas.
- Los nombres de los paquetes cambian de javax.* a jakarta.*. Esto implica que la actualización desde JEE 8\Jakarta EE 8 no es directa y exige refactorizar las importaciones o import de las API del código ya existente. Con el fin de hacer menos traumática la actualización, tenemos a nuestra disposición la librería Eclipse Transformer. Es capaz de renombrar los paquetes a nivel de bytecode (el código compilado) y evita tener que modificar el código. Para más información y ejemplos, consultar este artículo.
- Los esquemas de los XML cambian de nombre. Se pueden consultar en https://jakarta.ee/xml/ns/jakartaee/.
- Algunas especificaciones que hoy en día tienen poco valor abandonan el estándar: XML Registries, XML RPC, Deployment, Management y Distributed Interoperability (EJB 3.2 Core).
- Las especificaciones aumentan su número de versión principal, finalizando así la transición desde Oracle. Por ejemplo, JPA (Java Persistence API), publicada por última vez todavía bajo el seno del JCP con la numeración 2.2, se convierte en Jakarta Persistence 3.0.1.

La imagen muestra las principales especificaciones incluidas en Jakarta EE 9. El subconjunto Web Profile (perfil web) está orientado a la construcción de aplicaciones web arquetípicas y supone el grueso del contenido del curso. Las cinco dibujadas en color gris son opcionales: los proveedores están exentos de incluirlas en sus servidores de aplicaciones. Además, son candidatas a abandonar el barco: resultan irrelevantes con respecto al momento de su creación.
Jakarta EE 9.1
Esta revisión menor solo añade Java 11 como requisito. La publicación del curso comenzó antes de esta versión y ya se usaba Java 11, así que la vamos a ignorar. No habrá actualizaciones hasta la llegada y difusión de Jakarta EE 10 a finales de 2022\comienzos de 2023.
Servidores de aplicaciones
Desde una perspectiva práctica, la definición de Jakarta EE como un simple conjunto de APIs estandarizadas no es suficiente. Tenemos una para trabajar con bases de datos relacionales, otra orientada al desarrollo de servicios REST, un par relativas a la notación JSON… pero necesitamos la integración de todas ellas si queremos crear una aplicación completa. Vamos a dedicar mucho tiempo a ensamblar las piezas si no tenemos una plataforma de desarrollo que provea todo lo necesario.
Pues bien, esta plataforma existe y no podía haberse diseñado mejor: es una especificación llamada Jakarta EE Platform. Se asume que nos referimos a ella cuando simplemente hablamos de Jakarta EE. Sus implementaciones resultan especiales: son servidores de aplicaciones en los que se puede desplegar (ejecutar) cualquier aplicación basada en la versión y perfil de JEE\Jakarta EE con las que el servidor sea compatible. Para conseguirlo, deben incluir tanto las APIs como las implementaciones de todas las especificaciones. No tenemos que preocuparnos por seleccionarlas y empaquetarlas en nuestros proyectos y, lo más importante, ya están integradas para que funcionen en perfecta armonía.
Así pues, los servidores de aplicaciones son máquinas bien engrasadas listas para ejecutar nuestras gloriosas aplicaciones.

De acuerdo a lo que ya sabemos, los servidores de aplicaciones son intercambiables si la aplicación solo usa las APIs del estándar. Otro asunto son las configuraciones y la administración, dependientes de cada uno.
No obstante, la realidad es más árida. En demasiadas ocasiones tendremos que utilizar características específicas del servidor, o más bien de las implementaciones que incluye, porque son de gran ayuda (ya cité el caso de Hibernate ORM). Esto provoca que terminemos desarrollando para un servidor específico. A veces, varios de ellos incorporan las mismas implementaciones de algunas especificaciones, así que podemos utilizarlas manteniendo cierto nivel de portabilidad. ¿Y si queremos usar una implementación distinta a la que proporciona el servidor? No hay una respuesta universal a esta cuestión y depende de cada caso en concreto, aunque suele ser factible.

Tal y como muestra la imagen, existe una amplia variedad de servidores de aplicaciones y algunos ya son compatibles con Jakarta EE 9. En este curso voy a optar por uno de código abierto llamado WildFly (*). Si bien no dispongo de datos sobre su cuota de mercado, es con diferencia el que más he encontrado a lo largo de mi andadura profesional. Lo desarrolla la compañía Red Hat, todo un coloso del mundo Open Source, quienes lo utilizan como base de JBoss Enterprise Application Platform (JBoss EAP), servidor de aplicaciones con soporte comercial.
(*) Hasta 2013, WildFly se llamaba JBoss AS.
Otras alternativas de código abierto a considerar son Apache TomEE, Payara Server, Open Liberty y GlassFish. Este último forma parte de la donación de Oracle a la Fundación Eclipse. Es la implementación de referencia de JEE y, en cierto modo, lo sigue siendo para Jakarta EE pues los TCK se basan en sus librerías y debería ser el primer servidor compatible con cada nueva versión.
Para concluir esta sección, me gustaría señalar un error muy común. Los servidores de aplicaciones Jakarta EE \JEE suelen confundirse con servidores tan populares como Apache Tomcat y Eclipse Jetty que solo ofrecen las características imprescindibles para desplegar aplicaciones web (la especificaicón Servlet y unas pocas más). La distinción la haremos atendiendo a la clasificación del producto: son servidores, pero no «de aplicaciones». Si se quiere usar en ellos una especificación, la aplicación debe incluirla (API e implementación).
Microservicios con MicroProfile
Una de las grandes fortalezas de JEE es su estabilidad y madurez. Tengamos presente que las publicaciones de nuevas versiones están espaciadas tres o cuatro años. Esta lentitud supone un problema en un mundo tan cambiante como el del desarrollo de software. La aparición de nuevos estándares, arquitecturas, conceptos y, por qué no decirlo, modas, es incesante.
En los últimos tiempos hemos asistido al imparable auge -y abuso- de las arquitecturas basadas en microservicios con las miras puestas en la creación sistemas en la nube distribuidos, resilientes y escalables. Con el objetivo de afrontar con JEE el desarrollo de este tipo de aplicaciones y los retos que plantean, en 2016 surgió la plataforma MicroProfile, gestionada por la fundación Eclipse, y que desde entonces no ha dejado de progresar a gran velocidad. Consiste en un pequeño conjunto de especificaciones pertenecientes a JEE (CDI, JAX-RS, JSON-P, JSON-B) y otras propias que siguen la misma filosofía de estandarización con el fin de asegurar la compatibilidad de los desarrollos con múltiples proveedores.

Podemos considerar a MicroProfile como un complemento o extensión de JEE para trabajar con microservicios. Ambos pueden combinarse incluso en aplicaciones que sigan otro tipo de arquitecturas, por ejemplo el clásico «monolito». Asimismo, si bien los servidores compatibles con JEE no tienen por qué serlo también con MicroProfile y viceversa, algunos lo son.
A largo plazo, todo apunta la fusión de las dos plataformas. ¿Se convertirá MicroProfile en un perfil de Jakarta EE? El tiempo lo dirá. El principal escollo de esta hipotética integración es la gran diferencia existente en la cadencia de publicación que sigue cada una de ellas. De momento, la última versión de MicroProfile (4.0, diciembre de 2020) se basa en Jakarta EE 8 y no es compatible con Jakarta EE 9.
MicroProfile queda fuera del alcance del curso. Sin embargo, trataremos en profundidad las cuatro especificaciones de Jakarta EE en las que se fundamenta lo que ayudará al lector si en algún momento debe afrontar su aprendizaje.
Mirando al futuro
El futuro de Jakarta EE es estimulante. Se está trabajando en nuevas especificaciones tales como MVC o NoSQL y con el foco puesto en la construcción de sistemas nativos para la nube. No obstante, lo más prometedor es una ambiciosa política de actualizaciones que persigue la publicación de una nueva versión cada año. A este respecto, y por su naturaleza de estándar, debemos tener presente que cuando se lanza una versión es necesario esperar varios meses para que los proveedores adapten sus productos.
Si nos paramos a reflexionar, la velocidad de desarrollo de los marcos de trabajo y librerías que utilizamos es un arma de doble filo: una rápida evolución entrega con gran frecuencia características novedosas pero nos obliga a seguir un ritmo de actualización, tanto de conocimientos como del código ya escrito, que puede llegar a ser estresante y agotador.
Lo contrario tampoco es deseable. De hecho, unos párrafos atrás señalé que era la causa principal del advenimiento de MicroProfile. Una plataforma estancada durante años es incapaz de dar respuesta a las nuevas necesidades técnicas que van surgiendo y el mercado terminará dándole la espalda en favor de alternativas más modernas.
Esperemos que la fundación Eclipse, con el apoyo de toda la comunidad, consiga hacer avanzar la plataforma Jakarta con pies de plomo, sin prisa pero sin pausa, manteniendo su solidez. De un modo u otro, todos los programadores Java nos beneficiaremos: aunque no trabajemos con ella, usaremos sin remedio algunas de sus especificaciones.
Para estar al día de lo que se está «cociendo», recomiendo utilizar los siguientes recursos (todos en inglés).
- Listas de correos oficiales. Públicas y participativas, un magnífico ejemplo del espíritu de apertura y cooperación del proyecto EE4J. En esta dirección.
- El canal oficial en YouTube de Jakarta EE, lleno de presentaciones y encuentros virtuales que también abordan MicroProfile. En esta dirección.
- Un recopilador de publicaciones de blogs de primer nivel relacionados con Jakarta EE. En esta dirección.
- La cuenta oficial en Twitter. En esta dirección.
¿Convencido?
Recopilo los puntos fuertes de Jakarta EE como plataforma para desarrollar nuestros proyectos. Algunos ya los he citado, y la justificación de todos ellos se deduce de las explicaciones de este capítulo.
- Ofrece lo necesario para crear con presteza desde pequeñas APIs REST hasta grandes sistemas basados en microservicios, pero sin exigencias: toma solo que necesites.
- Fácil de configurar. Todas las especificaciones ya están integradas y disponibles en el servidor.
- Adiós a la locura de las actualizaciones. Un marco de trabajo estable al servicio de los programadores y no al revés.
- Libertad de elección y portabilidad. Escoge la implementación que más se adapte a tus necesidades en cada momento, incluyendo la posibilidad de soporte comercial. Y, por supuesto, con alternativas de código abierto gratuitas.
- Las APIs son numerosas pero pequeñas y simples. La curva de aprendizaje es suave y con pocos conocimientos se puede hacer mucho.
- Excelente documentación oficial. Complementada por una buena bibliografía para las especificaciones más importantes.
- Desarrollada con total transparencia por una comunidad abierta y participativa tutelada por la Fundación Eclipse con el apoyo de gigantes de la industria como Oracle, Red Hat o IBM. Su futuro está garantizado y no depende de la estrategia de una corporación.
Bola extra: Migración desde JEE
Los pasos para migrar un proyecto JEE a Jakarta EE 9 o superior se pueden deducir de las novedades de este último que cité anteriormente. Cada proyecto suele ser un mundo y tener múltiples peculiaridades, pero con carácter general, este es el proceso.
1 – Cambiar las dependencias en el pom.xml. Por ejemplo, si importamos toda la especificación, de
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
a
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>9.0.0</version>
<scope>provided</scope>
</dependency>
2. Refactorizar los nombres de los paquetes javax.* a jakarta.*. Es fácil de hacer con un IDE, incluso IntelliJ Ultimate provee una herramienta específica.

3. Cambiar también los xsi de los xml.
4. Si todavía no estamos trabajando con Java 11, es el momento para hacerlo.
5. Utilizar para el despliegue un servidor de aplicaciones que soporte la versión de Jakarta EE, tal y como haríamos con JEE.
6. Si tenemos librerías de terceros que usen clases de javax.* en tiempo de ejecución y todavía no tienen versiones compatibles con Jakarta EE, mientras tanto podemos adaptarlas con la herramienta Eclipse Transformer que ya mencioné. De hecho, es una estrategia que están adoptando algunos proveedores.