La gente que no programa Java o que lleva mucho tiempo sin programar Java tiene la percepción de que Java se ha quedado estancado en el tiempo. Pero luego se lleva las manos a la cabeza cuando ve que Java ya va por la versión 20. ¿Es un truco de marketing? Vamos a ver qué está pasando por debajo.
El nuevo calendario de publicación de Java
Hasta la versión 6 de Java, publicada allá por 2006, salía una versión de Java cada año o cada dos años. Cada versión traía un nuevo conjunto de APIs y tenía mejoras sustanciales en el lenguaje de programación. Sin embargo, esta versión también fue la que inició el invierno de Java.
Hubo que esperar hasta el año 2011 para ver una nueva versión de Java, la versión 7. En este caso, hubo una serie de problemas y retrasos con la implementación de las nuevas funciones del lenguaje de programación que derivaron en tener que posponer la publicación más tiempo del deseado por el equipo de trabajo de Sun, posteriormente Oracle. Similarmente, hubo que esperar más años de lo deseable para tener una versión nueva de Java, saliendo Java 8 en 2014.
Después de estos dos eventos, el equipo de desarrollo de Java hizo una serie de cambios al lenguaje para asegurar que una nueva función conflictiva no retrasaba la publicación de toda una milestone del lenguaje de programación. El problema de retrasar la publicación de una versión del lenguaje de programación es que el resto de funciones que sí están operativas y listas para ver la luz tienen ahora que esperar a ver la luz, y eso no es dinámico.
Resulta irónico que un lenguaje tan extendido en el mundo de la programación ágil como Java sea… tan poco ágil. Por eso, decidieron adoptar a partir de la versión 9 del lenguaje de programación un enfoque orientado a sprints.
A partir de la versión 9 de Java, sale una nueva versión de Java cada 6 meses. Esté como esté el lenguaje. De golpe se explica por qué vamos ya por la versión 20. Debido a que salen dos versiones cada año, desde 2017 llevamos ya 11 versiones.
¿6 meses no es poco tiempo para un lenguaje “empresarial”?
Probablemente pienses que cada 6 meses todo el mundo migra su máquina virtual a la siguiente versión para poder aprovecharse de las últimas funciones del lenguaje de programación. La realidad es que esto no es ni de lejos así, por dos razones.
En primer lugar, porque sería algo que no muchos equipos de trabajo estarían dispuestos a tolerar. ¡Pero si todavía quedan sitios donde se compila contra el JDK 7 o versiones inferiores de la plataforma JavaSE! Muchos administradores de sistemas perderían el pelo y no dormirían por la noche si cada 6 meses tuviesen que actualizar dos veces al año la máquina virtual de Java que corre en sus servidores y CPDs.
Sin embargo, la segunda razón por la que no ocurre esto es porque 6 meses normalmente es poco tiempo para que Java tenga funciones nuevas. Java publica una versión cada 6 meses, pero la mayoría de funciones nuevas tardan más de 6 meses en estar listas. Entonces, ¿cómo se conecta todo esto? Y lo más importante, ¿cómo se proponen estas nuevas funciones?
JEPs, Incubadoras, versiones previas…
Que Java no evolucione es un mito. La realidad es que nunca ha evolucionado tan deprisa. El proceso de adquisición de nuevas funciones es cierto que hoy en día está más enfocado en dos tipos de nuevas funciones:
- Aquellos patrones que se sabe que funcionan en otros lenguajes de programación suelen ser importados en el lenguaje Java. Así es como se han adquirido funciones nuevas como los records o las switch-expressions.
- Aquellos puntos débiles de la plataforma Java son mejorados para incrementar el rendimiento de la máquina virtual o la ergonomía de trabajo. Así es como se ha migrado a módulos el JDK, entre otras funciones (un nuevo sistema de módulos nativos que sustituya a JNI, por ejemplo).
El proceso es bien simple. Para mejorar el lenguaje de programación se abre un JEP (JDK Enhancement Proposal, o Propuesta de mejora del JDK). Un JEP es una propuesta para mejorar el lenguaje. En su página web podemos ver la lista de JEPs, y vemos que existen muchas propuestas abiertas, todavía más si consultamos los Drafts al final de la página, que son las funciones que han sido propuestas pero no aceptadas todavía.
Si el JEP es aceptado, se comenzará a trabajar en él y se desarrollará una especificación con la documentación, y alguien se ocupará de programar el soporte dentro de la máquina virtual de Java y del JDK.
Los JEPs también siguen un ciclo de trabajo de sprints que se sincroniza con el de las propias versiones de Java, así que si es aceptado, se comenzará a trabajar en él cuando se inicie el sprint de la versión de Java a la que apunta, y en condiciones normales se tendrá lista la función a la vez que termine el sprint, para valorar su inclusión en la versión de Java que vaya a salir.
Sin embargo, sería raro que la función esté terminada en 6 meses. Para empezar, porque conviene conocer la aceptación de la nueva función por parte de la comunidad. Y además, porque seguramente haya errores iniciales en el QA. Por esta razón, lo normal es que las nuevas funciones nazcan en estado de incubación o de vista previa, según se describe respectivamente en los JEP 11 y 12.
De modo que lo normal es que durante un par de sprints, esa nueva función vaya iterando, y su JEP vaya evolucionando, hasta llegar a un punto estable en el cual se puede dar como terminada la función y marcarla como estable, momento en el que deja de estar en incubación o vista previa y sale en todo su esplendor.
Cómo usar características en incubación y previa
Si te bajas una versión del JDK que tiene características en incubación o en previa, el compilador rechazará activar esas funciones por defecto a no ser que actives la opción --enable-preview en el momento de compilar.
Esto se hace, fundamentalmente, para que la persona que escribe el comando de compilación “acepte” las normas de las funciones en previa, que son:
- Que la función no está completa y por lo tanto puede tener irregularidades, no tener todas las características listas, o no funcionar como cabe esperar.
- Que la función puede cambiar en futuras versiones de Java, rompiendo el código previamente escrito si se trata de compilar contra una revisión futura del JDK.
Las LTS: el secreto a largo plazo de las nuevas versiones de Java
Aproximadamente cada 3 años (o cada 6 sprints, o cada 6 versiones de Java), el lanzamiento de ese semestre se considera un lanzamiento LTS (Long Term Support). Estas son las versiones estables de Java, y si quieres utilizar el ciclo de lanzamiento bianual o trianual tradicional de Java (por ejemplo, Java 7 - Java 8 - Java 9), este es el tipo de versiones que tienes que tener en cuenta. Desde que Java usa este calendario, las versiones LTS de Java han sido Java 11 y Java 17. Sin embargo, en los últimos años se han incorporado tantas funciones nuevas al lenguaje de programación Java, que han decidido declarar la versión 21 como próxima versión LTS.
Será por lo tanto en otoño de 2023 cuando veremos la próxima versión LTS. En este tipo de versiones, la mayoría de funciones que han tenido tiempo de incubación suficiente pasan a estable, por lo que se convierten en nuevas características del lenguaje de programación Java, que pueden usarse de manera estable para escribir código nuevo y que simplemente funcionarán sin tener que hacer nada más.
Estas son también las versiones de Java que muchos de los proveedores de entornos OpenJDK, como Microsoft o AWS Coretto, se limitarán a proporcionar, por ser más estables y por lo tanto durar más años que si estuviesen cada 6 meses compilando y empaquetando máquinas virtuales.