Consideraciones generales al actualizar proyectos Java empresariales desde Java 8 hacia Java 11

En este megapost mi objetivo es consolidar todas las dificultades (y soluciones) que he enfrentado al actualizar proyectos Java EE y/o MicroProfile desde Java 8 hacia Java 11. Es un hecho que Java 11 trajo consigo muchas características que cambiaron el ecosistema de Java y podrían ser problemáticas durante nuestras actualizaciones.

Aunque mi enfoque es Java empresarial, esta información puede servir de referencia para actualizaciones con otros frameworks/runtimes.

Este ha sido el post más largo que escribo en varios años por lo que agradecería que lo compartieran 😬.

¿Es posible actualizar proyectos Java EE/MicroProfile desde Java 8 hacia Java 11?

Si. En anteriores ocasiones he actualizado junto a mi equipo dos proyectos que considero épicos (más de 3 años de desarrollo) con las siguientes métricas:

Proyecto 1: Un sistema de gestión empresarial (MIS)

Nabenik MIS
  • Tiempo invertido en la migración: 1 semana
  • Módulos: 9 EJB, 1 WAR, 1 EAR
  • Clases: 671
  • Líneas de código: 39480
  • Inicio del proyecto: 2014
  • Plataforma original: Java 7, Wildfly 8, Java EE 7
  • Plataforma actual: Java 11, Wildfly 17, Jakarta EE 8, MicroProfile 3.0
  • Cliente web: AngularJS

Proyecto 2: Un sistema de venta y geocerca

Medmigo REP
  • Tiempo invertido en la migración: 3 semanas (por varios errores en upstream)
  • Módulos: 5 WAR/Microservicios
  • Clases: 348
  • Líneas de código: 17160
  • Inicio del proyecto: 2017
  • Plataforma original: Java 8, Glassfish 4, Java EE 7
  • Plataforma actual: Java 11, Payara 5, Jakarta EE 8, MicroProfile 3.2
  • Cliente web: Angular

¿Porqué debería actualizar hacia Java 11?

Como todo en informática la respuesta es: depende. Los motivos por los cuales he decidido actualizar suelen ser los siguientes:

  1. Reducir la superficie de ataque al contar con dependencias actualizadas, especialmente Open Source
  2. Reducir el débito técnico y preparar mis proyectos para un Java más dinámico
  3. Aprovechar las mejoras de desempeño en las nuevas versiones de Java
  4. Aprovechar las nuevas características de Java como lenguaje
  5. Dormir bíen gracias a esas ventajas técnicas

¿Porqué es dificil actualizar un proyecto Java EE desde Java 8 hacia Java 11?

De acuerdo a mi experiencia y en orden de prioridades, por los siguientes motivos:

Cambios en la frecuencia de lanzamiento de Java

Actualmente tenemos dos grandes ramas de máquinas virtuales de Java

  • Java LTS: El cual está pensado para soporte de largo plazo (3 años), siendo la última versión Java 11
  • Java current: El cual está pensado para tener ciclos de vida cortos (6 meses) y recibir características de forma rápida, el cual al momento de escribir este articulo es Java 15

El raciocinio detrás de este cambio es que Java como plataforma necesitaba dinamismo y es más fácil recibir pequeñas características cada seis meses, con lo cual estoy totalmente de acuerdo.

Sin embargo es un hecho que la mayoría de frameworks empresariales están enfocando sus runtimes hacia Java 11 para estar en linea con ciclos de soporte de la JVM más largos.

El sistema de módulos de Java 9 y sun.misc.unsafe

El culpable de todas mis angustias

Una de las mayores criticas sobre Java fue la distribución monolítica de la maquina virtual de Java. Bajo este esquema, una instalación típica de Java Developer Kit incluía paquetes como AWT, Swing o el plugin para ejecución de Applets en navegadores web, los cuales no servían de nada para una aplicación backend.

Aunque esto se solventaba parcialmente con paquetes headless en distribuciones Linux o la instalación Server JRE, lo cierto es que con la llegada de Docker y microservicios, el ecosistema Java necesitaba mejores formas de distribuir la JVM.

Consecuentemente, en 2017 recibimos la versión 9 de Java cuya mayor característica fue la introducción del sistema de módulos de Java o JPMS, mediante el cual Java se volvía una plataforma modular pero a cambio exigió un control de acceso más estricto sobre paquetes internos de la JVM.

Resulta que, durante la encapsulación de módulos internos algunos de estos se consideraron críticos con un uso generalizado, y muchas bibliotecas populares, por ejemplo. Hibernate, ASM, Hazelcast: utilizaron estos componentes internos para obtener rendimiento, especialmente sun.misc.unsafe que creó un efecto dominó sobre el ecosistema Java.

Dado que muchas de estas bibliotecas se consideran fundamentales para el ecosistema de Java, la mayoría de los tiempos de ejecución tuvieron que esperar / contribuir para actualizar estas bibliotecas para Java 9, considerando que algunas de estas bibliotecas internas eran API no públicas propietarias (por lo tanto, los detalles cambiaron), y se encapsularon algunos módulos no críticos.

Eliminación de CORBA y los módulos de Java EE en el JDK

Otro cambio importante en Java 9 fue que varios modulos de Java EE y CORBA fueron marcados como «Deprecated» para ser eliminados en futuras versiones de OpenJDK.

A partir de Java 11 este cambio se hizo realidad y varios módulos de OpenJDK que eran incluidos para soportar Java EE fueron eliminados de OpenJDK, con esto, los siguientes paquetes ya no son parte de OpenJDK:

  • java.xml.ws (JAX-WS) para creación de servicios SOAP
  • java.xml.bind (JAXB) para procesamiento de XML
  • java.activation (JAF)
  • java.xml.ws.annotation (Common Annotations)
  • java.corba (CORBA)
  • java.transaction (JTA)
  • java.se.ee (Módulo agregador)
  • jdk.xml.ws (Herramientas para JAX-WS)
  • jdk.xml.bind (Herramientas para JAXB)

Para fines prácticos esto significó que ya no es posible generar y ejecutar clientes SOAP (o CORBA) directamente desde la JDK, y ahora es necesario agregar los proyectos upstream como en cualquier otra biblioteca.

El raciocinio detrás de este cambio fue que los módulos eran incluidos como una conveniencia para soportar la «nueva era» de Web Services en los 90s, pero que al final del día eran mantenidos por proyectos Upstream de forma independiente y los publicaban en Maven Central.

Independencia de JavaFX en OpenJDK

De la misma forma que los módulos de Java EE, en Java 11 el módulo de JavaFX fue removido y desacoplado de la distribución de Java Developer Kit, luego de 10 años de desarrollo.

Al igual que Java EE, el modulo sobrevive fuera de la distribución estándar del Java Developer Kit, y de hecho existe actualmente un proyecto independiente mantenido por la comunidad, además de empresas como Gluon, Azul Systems y Oracle -i.e. OpenJFX– para que JavaFX evolucione a su propio ritmo.

Entornos de desarrollo integrado y servidores de aplicaciones

Al igual que lo que pasó con las bibliotecas, los IDEs tuvieron que prepararse para la transición hacia Java modular, al menos en tres niveles:

  • El IDE como programa Java debe ser compatible con JPMS
  • El IDE debe soportar Java 9, 10, 11 … como lenguaje de programación
  • El IDE es la base de un ecosistema de plugins que TAMBIÉN debe actualizarse para soportar JPMS
  • Estos plugins a su vez deben ser compatibles con entornos de ejecución (servidores) compatibles con JPMS

Con esto tanto Netbeans como IntelliJ y Eclipse se actualizaron paulatinamente hacia Java 9 y superiores, PERO no podían dar garantías que todo el ecosistema estuviera actualizado.

Acá una situación común es que luego de instalar Java 11 y un IDE como Eclipse con soporte para Java 11, nuestro proyecto aun fuera incompatible porqué:

  • Utilizábamos la versión un plugin -e.g. Glassfish- que aun NO era compatible con JPMS
  • Utilizabamos un application server -e.g. Glassfish- que en la época aun NO era compatible con JPMS

Ok, ¿Como actualizo proyectos?

Dadas las situaciones anteriores, actualizar un proyecto desde Java 8 (o 7) es una tarea que requiere distintas verificaciones, por lo cual suelo una estrategia de 8 pasos:

  1. Verificar la compatibilidad del entorno de ejecución
  2. Verificar que versión de Java necesito
  3. Configurar nuestro entorno de desarrollo para soportar múltiples JVM
  4. Verificar el IDE
  5. Actualizar y configurar Maven
  6. Actualizar las dependencias del proyecto
  7. Incluir manualmente las dependencias de Java/Jakarta EE
  8. Ejecutar múltiples JVM en producción

1. Verificar el entorno de ejecución

Mike Loukides de O’Reilly considera que existen dos tipos de programadores y eso se hace evidente en Java. Por un lado están los programadores que crean los frameworks, bibliotecas y rutinas de bajo nivel y por otro lado están los programadores que utilizan estas herramientas para crear experiencias, productos y servicios.

Java Empresarial se encuentra en el segundo grupo, donde descansamos sobre hombros de gigantes y por este mismo motivo antes de intentar planificar cualquier actualización debemos de verificar que nuestro runtime/herramienta/servidor sea compatible (al menos) con Java 11. Afortunadamente el ecosistema de Java 11 ya es bastante maduro y varios proyectos fundamentales de Java han realizado la transición exitosamente, incluyendo:

De hecho en bastante improbable que una biblioteca aun no soporte Java 11, pero si ese fuera el caso debemos indagar con el fabricante/comunidad si el proyecto no ha muerto, sus planes para el futuro o pensar en contribuir con el desarrollo para que esto suceda.

2. Verificar que versión de Java necesito

Una segunda limitante no técnica que podríamos enfrentar es que para una determinada versión de un producto necesitamos un Java Developer Kit en particular, lo que se conoce como el proceso de certificación.

En jerga informática solemos decir que un paquete de software esta certificado cuando el fabricante brinda garantías de que el mismo funcionara de forma correcta bajo ciertas condiciones/entorno. Dicho de otra forma puede que el software ya funcione bien bajo Java 11 pero es necesario tener la garantía legal y de soporte para proceder con una actualización.

Un caso ejemplo es WebLogic, que necesita por contrato una compilación especifica de OpenJDK para ejecutarse (Oracle Hotspot) y una versión mínima para aplicar a contratos de soporte.

Otro podría ser SAP el cual requiere que se utilice la compilación de OpenJDK soportada por SAP (SAP JVM) para ejecutar sus productos.

3. Soportar múltiples JVMs en desarrollo

Al ser la actualización un proceso experimental de tipo prueba y error, una buena idea es soportar multiples JVMs en desarrollo, y para esto existen diversas herramientas:

SDKMan

Disponible para entornos UNIX (Linux, Mac, Cygwin, BSD) permite la instalación de varias herramientas útiles en el ecosistema Java como Maven, Gradle, Leiningen, Micronaut y diversas compilaciones de OpenJDK -e.g. AdoptOpenJDK, Amazon Correto, Oracle GraalVM-.

jEnv

También disponible para entornos UNIX (Linux, Mac, Cygwin, BSD) es un script de configuración de entorno. Tiene la particularidad que permite configurar la JVM a nivel de sistema, red y usuario. Esta es mi elección personal ya que permite gestionar JVMs instaladas bajo diversos formatos.

En el caso de Windows la forma más fácil que he encontrado es automatizar la tarea con archivos .bat. Pero para serles franco no uso Windows para trabajo/desarrollo desde el año 2006. Agradecería cualquier comentario al respecto.

4. Verificar el IDE

Recordemos que un IDE se compone de 3 partes

  1. La plataforma
  2. El soporte al lenguaje de programación
  3. Las extensiones para soportar herramientas especificas

Tanto Eclipse, NetBeans, IntelliJ IDEA y Visual Studio Code tienen versiones compatibles con Java 11 por lo que la tarea es actualizar hacia estas versiones.

Luego de la actualizacion y la ejecución sobre Java 11, debemos verificar si nuestras extensiones funcionan correctamente. Especialmente si se utilizan conectores hacia servidores de aplicaciones.

5. Actualizar y configurar Maven

Aunque existen otros sistemas como Ant, Gradle o Bazel, en mi opinión Maven sigue siendo el estándar de facto en la gestión de la configuración y dependencias de proyectos con Java.

Además de actualizar nuestra instalación de Maven, debemos tomar en cuenta que Maven como proyecto funciona a través de extensiones, las cuales se pueden forzar arbitrariamente. Por tal motivo debemos de estar seguros cual es la versión de plugins que utilizaremos en cada proyecto a compilar. En esta línea Maven cuenta con un POM (listado de dependencias) con versiones predeterminadas que deberíamos incluir en nuestros proyectos.

Una forma rápida de verificar las extensiones es utilizar versions-maven-plugin

<plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>versions-maven-plugin</artifactId>
      <version>2.8.1</version>
</plugin>

El cual tiene un «goal» especifico para mostrarnos las versiones disponibles de los plugins de Maven

mvn versions:display-plugin-updates

Como regla general debemos utilizar las últimas versiones estables para no tener problemas con Java 11.

Así mismo debemos de configurar Maven para que sea capaz de compilar código nivel 11, lo cual se hace generalmente en dos puntos del archivo de configuración.

En la propiedad maven.compiler.x:

<properties>
        ...
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
</properties>

En maven-compiler-plugin si lo tenemos configurado de forma explitica:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>11</release>
    </configuration>
</plugin>

Como medida de compatibilidad el équipo de la JVM disponibiliza desde Java 9 la bandera illegal-access para permitir acceso reflectivo a modulos internos de la JVM, esto quiebra la teoría de separación por modulos de JPMS pero permiten aumentar la compatibilidad de algunos paquetes con histórico acceso a clases internas.

En ocasiones necesitaremos invocar las extensiones con esta bandera, por en surefire y failsafe los cuales son utilizados tradicionalmente en Java EE para invocar la ejecución servidores de aplicaciones que necesitan este argumento:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <argLine>
            --illegal-access=permit
        </argLine>
    </configuration>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.22.0</version>
    <configuration>
        <argLine>
            --illegal-access=permit
        </argLine>
    </configuration>
</plugin>

6. Actualizar las dependencias de mi proyecto

Como se ha mencionado en la parte teórica del proyecto, es necesario actualizar todas las dependencias del proyecto hacia su última versión estable y/o compatible con Java 11.

Tomando en cuenta que a veces el salto mayor de dependencia -e.g. Flyway 4 hacia Flyway 6- implica un cambio en el API del proyecto, acá se debe considerar que podría ser necesario un refactoring de nuestro código, para ser sinceros esta es la parte que podría requerir más tiempo y lo que detiene a la mayoría de actualizaciones.

Un buen paso inicial es verificar las ultimas versiones estables utilizando también versions-maven-plugin:

mvn versions:display-dependency-updates

La salida nos informara que dependencias tienen nuevas actualizaciones:

Al momento de actualizar también debemos estar seguros que las dependencias son compatibles con mi entorno de ejecución y podría afirmar que esta es una fortaleza poco conocida de Java EE, al ser Java EE una dependencia única los servidores de aplicaciones/microframeworks se encargan de resolver conflictos de dependencias y suele ser una experiencia bastante fácil frente a abordajes «hazlo tu mismo».

7. Agregar los paquetes faltantes de Java EE (y tal vez migrar hacia Jakarta EE)

Aunque en proyectos modernos (REST) esto probablemente no sea un problema, en proyectos basados en Web Service SOAP o en bibliotecas muy especificas sera necesario que agreguemos las dependencias que fueron removidas de OpenJDK.

En el mundo Java EE por cada paquete suele haber dos dependencias:

  • El API o interfaz de programación
  • La implementación de referencia con el código del API

En este punto vale la pena evaluar tambien si no es buena idea realizar el cambio haciar Jakarta EE.

La historia corta es que en 2017 Oracle liberó la mayoria de propiedad intelectual sobre Java EE para que la especificación reciba mayores contribuciones de la comunidad, naciendo así el proyecto Jakarta EE bajo la fundación Eclipse.

Para fines prácticos Jakarta EE 8 tiene las mismas capacidades técnicas de Java EE 8 y los mismos paquetes. Actualmente la mayoria de servidores de aplicaciones modernos y Tomcat ya son compatibles con Java EE 8(WebLogic lo tiene considerado para el futuro).

Si deseamos hacer actualización y nuestro entorno de ejecución la soporta, debemos de reemplazar la dependencia de Java EE 8:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0.1</version>
    <scope>provided</scope>
</dependency>

Por:

<dependency>
    <groupId>jakarta.platform</groupId>
    <artifactId>jakarta.jakartaee-api</artifactId>
    <version>8.0.0</version>
    <scope>provided</scope>
</dependency>

Asi mismo, puede que necesitemos las siguientes dependencias para compilar nuestro proyecto Java EE que originalmente eran parte de OpenJDK:

Java Beans Activation

Java EE

<dependency>
    <groupId>javax.activation</groupId>
    <artifactId>javax.activation-api</artifactId>
    <version>1.2.0</version>
</dependency>

Jakarta EE

<dependency>
    <groupId>jakarta.activation</groupId>
    <artifactId>jakarta.activation-api</artifactId>
    <version>1.2.2</version>
</dependency>

JAXB (Java XML Binding)

Java EE

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

Jakarta EE

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>2.3.3</version>
</dependency>

Implementación

<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

JAX-WS

Java EE

<dependency>
    <groupId>javax.xml.ws</groupId>
    <artifactId>jaxws-api</artifactId>
    <version>2.3.1</version>
</dependency>

Jakarta EE

<dependency>
    <groupId>jakarta.xml.ws</groupId>
    <artifactId>jakarta.xml.ws-api</artifactId>
    <version>2.3.3</version>
</dependency>

Implementación (runtime)

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-rt</artifactId>
    <version>2.3.3</version>
</dependency>

Implementación (standalone)

<dependency>
    <groupId>com.sun.xml.ws</groupId>
    <artifactId>jaxws-ri</artifactId>
    <version>2.3.2-1</version>
    <type>pom</type>
</dependency>

Java Annotation

Java EE

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Jakarta EE

<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>1.3.5</version>
</dependency>

Java Transaction

Java EE

<dependency>
    <groupId>javax.transaction</groupId>
    <artifactId>javax.transaction-api</artifactId>
    <version>1.3</version>
</dependency>

Jakarta EE

<dependency>
    <groupId>jakarta.transaction</groupId>
    <artifactId>jakarta.transaction-api</artifactId>
    <version>1.3.3</version>
</dependency>

CORBA

En el caso de CORBA, existe el proyecto ORB dentro de Eclipse pero sinceramente es terreno poco explorado para mi. Solo me queda desearles buena suerte.

8. Ejecutar multiples JVMs en producción

Si todo compila, se ejecuta, los tests de regresión funcionan, podriamos decir que estamos ante una migración exitosa.

Sin embargo si nuestra empresa es una «Java Shop» es probable que tengamos varios proyectos con diversos runtimes y versiones de Java y no podamos actualizar todos al mismo tiempo por lo que suele ser una buena idea ejecutar servidores cono diversas versiones de Java instaladas.

La buena noticia es que la mayoria de distribuciones Linux ofrecen mecanismos para instalar/ejecutar diferentes versiones de JDK directamente desde el repositorio, las cuales funcionan bien una al lado de la otra.

Por ejemplo Oracle Linux ofrece OpenJDK 8, 11:

Al utilizar Oracle Hotspot mediante versiones en RPM obtendremos el mismo efecto, ya que sistemas basados en YUM suelen identificarlo como una alternativa Java:

En el caso que necesitemos un sistema «limpio» tambien es una buena idea distribuir nuestra aplicacion como un contenedor de docker, sabiendo que la mayoria de imagenes de JDK se encuentran disponibles en Docker Hub:

En el caso de Windows, mi recomendación es utilizar Docker ya que el mecanismo para tener diferentes JVM directamente en el sistema es el mismo que en desarrollo, usar archivos .bat y esperar lo mejor.

Programación en vivo: Creando un microservicio con Kotlin, Jakarta EE, MicroProfile y Payara Micro

En esta sesión de LiveCoding creamos desde 0 un microservicio con Kotlin que incluye configuración con Maven, una API REST con JAX-RS, Inyección de dependencias con EJB/CDI y persistencia hacia base de datos vía JPA utilizando H2.

Los slides se encuentran disponibles en Slideshare

Instalación de Java 11 en Windows, Linux y MacOS

Recientemente di un curso de microservicios/Java y me di cuenta que mi video de «instalación de Java» ya no está vigente, entonces lo actualicé hacia los 3 sistemas operativos y 3 casos de uso. Pero para divertirme, incluí la creación de una API rest como cierre de cada instalación.

En el primer video instalamos Oracle JDK y NetBeans 12 sobre MacOS, luego creamos una API rest con Payara y Jakarta EE

En el segundo video instalamos OpenJDK desde el repositorio con Visual Studio Code y Ubuntu LTS. Despues creamos una API utilizando MIcroProfile y Oracle Helidon.

Por ultimo instalamos OpenJDK de AdoptOpenJDK con Eclipse IDE en Windows 10, creando un API con Javalin.

Para ser sincero este video siempre lo hago para «no perder tiempo» de clase en la instalación durante mis cursos, pero quien sabe si más personas lo encuentren útil.

Actualizando aplicaciones Java EE desde Java 8 hasta Java 11 y llevandolas a la nube

Esta es la grabación «raw» de la conferencia titulada «Desde Java 8 on premise para Java 11 en la nube, hasta Java 14 en el infinito» en la cual exploramos cuales son las limitantes y características técnicas que un proyecto debe considerar al momento de actualizar versiones de Java. Especialmente desde Java 8 hacia Java 11.

La charla fue parte del Oracle #GroundBreakersTour 2020 https://www.laouc.org/equipo/de-java-8-on-premise-para-java-11-na-nuvem-ate-java-14-no-infinito/

Como de costumbre, los slides se encuentran disponibles en Slideshare

El código fuente se encuentra disponible en GitHub

https://github.com/tuxtor/demo-java11

Tres meetups de Java alrededor del mundo

Luego de que casi me lleva la calaca con el coronavirus y ponerme al día con mis pendientes de trabajo, regresé a una de las actividades que más me gustan: Lenguajes de programación y comunidades de software, por lo que tuve la oportunidad de viajar virtualmente esta semana en mis horarios de «descanso».

En mi primera parada fui invitado por uno de mis viejos amigos que ahora es profesor en el Instituto Federal Farroupilha en Rio Grande do Sul, Brasil. En este meetup hablamos de lenguajes de programación y como Java se encaja en el mundo moderno luego de 25 años en el mercado.

El meetup está en portugués:

https://www.youtube.com/watch?v=DFNqzy8h1_M

La siguiente parada fue Merida Yucatan, gracias a Ésau uno de los lideres de la comunidad quien me invitó a participar como ponente en su meetup mensual. En esta charla un poco más técnica hablamos de errores comunes del desarrollador Java al momento de implementar controles de seguridad en sus aplicaciones, especialmente enfocado en Jakarta EE y MicroProfile, y como mejorar/parchar los errores mediante el OWASP Top 10:

La parada final fue una transmisión un poco más relajada con JoeDayz, uno de los canales de programación más vistos de América Latina. Junto a José y su audiencia durante dos horas tuvimos una charla informal acerca de la evolución de los diferentes lenguajes y plataformas que se utilizan actualmente y porqué el mundo hoy en día es eminentemente políglota.
Lo mejor de esta charla es que realmente no tuve que preparar ningun slide/demo, fue más bien un «podcast» en vivo donde el rumbo lo marcó la audiencia:

A la larga estoy seguro que esta sera la única forma de viajar durante 2020, entonces de lo malo hay que sacar lo bueno :).

Consejos y el camino del desarrollador de software

Esta es una grabación de la charla denominada «Consejos y el camino del desarrollador de software» en el cual intento explicar lo más imparcialmente posible como funciona la carrera típica de desarrollador de software, tipos de desarrollador por función, niveles -i.e junior, mid, senior, architect- asi como algunas consideraciones de lo que he visto en estos 10 años.

Como de costumbre los slides se encuentran en Slideshare:

Me contagié de COVID y esto aprendí mientras me recuperaba

Un pingüino enfermo

Si tuviera que describir lo que pasé en una frase seria «el COVID se siente como correr una maratón con mascarilla luego de que Mike Tyson te golpeara durante 10 días seguidos«.

Diferente de lo que muchas personas piensan, la enfermedad es muy real, y el sentimiento de asfixia te hace pensar que esa podría ser tu última noche y en mi caso moriría solo. Mi caso fue catalogado como moderado en la escala de 1-asintomático, 2-leve, 3-moderado y 4-severo.

Mi objetivo con este post es escribir mi experiencia para recordar en unos años como sobreviví, lo que sufrí, las cosas que aprendí y como gracias a Dios y al seguimiento del doctor Pedro Artero, salí adelante.

¿Que pienso de los que niegan la enfermedad o la minimizan?

Doña chonita

Están bien imbéciles.

El COVID es una enfermedad que mal tratada te puede matar en 14 días. Nadie es imprescindible en un trabajo, si no cuidas tu salud y mueres ten por seguro que tu jefe simplemente te reemplazara, no hay trabajo que valga el riesgo de morir sin despedirte de los tuyos.

No es una gripona y tampoco es una enfermedad inventada, es una enfermedad que en casos moderados-severos te va a llevar a una neumonía en menos de una semana.

Un caso moderado en realidad no significa que no vas a sentir nada, más bien significa que no necesitaste oxigeno de forma artificial, pero no por esto dejan de ser malos. La clave según lo que viví es tratarse lo más rápido posible.

¿Mi perfil y como me contagié?

Tux

A pesar de que no tengo un perfil «atlético» me considero alguien saludable. Realizaba al menos 12 viajes por año (muchos como mochilero), sin diabetes, hipertensión, obesidad, me ejercitaba regularmente antes de la pandemía, no comía mucha comida chatarra y trabajo desde casa. Logré llegar hasta los 100 días de encierro sin mayores sobresaltos pero cometí un único error: Salir por alimentos.

Dado que salia una vez a cada 15 días tengo bastante claro en mi línea de tiempo que me contagié en uno de estos dos lugares:

El supermercado o en la salida a la tienda de mi cuadra por un helado.

Debo decir que siempre salí con mascarilla pero como sugiere la evidencia nueva en Nature, el COVID seguramente también se transmite por aire y en estas dos ocasiones no usé un respirador N95 porque se me habían acabado.

¿Que cosas aprendí de este proceso?

  • La gente con diabetes e hipertensión es especialmente sensible a la enfermedad y el motivo es básicamente que tu corazón y pulmones trabajan bajo muchísima más presión de lo que comúnmente lo hacen mientras tu cuerpo lucha contra el COVID. No es una sentencia de muerte pero no debe tomarse a la ligera.
  • La toma de temperatura en la entrada a locales será básicamente una perdida de tiempo. Los días que tuve fiebre alta fueron pocos en comparación a los días de la enfermedad, incluso enfermo pasaba sin inconvenientes esos controles cuando iba a hacerme exámenes.
  • Ninguna medida es extrema, hasta este momento no se como me contagié pero si se que ademas de la mascarilla pude haber ido con careta y tal vez no estuviera escribiendo este post.
  • Que un caso sea moderado no es que uno se dedique a ver Netflix y descansar tranqui con un libro. Solo significa que no te pusieron oxigeno y la linea es delgada hacia un caso severo.
  • La clave es recibir tratamiento y seguimiento rápido. Por eso Guatemala fracasará contra el COVID, la cobertura en salud es inexistente.
  • La mayoría de pruebas que se anuncian en la tele son probablemente de centros privados, ni para eso sirve el gobierno. El día que me hice la prueba el centro donde la realicé hizo casi 100 pruebas.
  • En un caso moderado de COVID el tratamiento (termometro, oximetro, anti inflamatorios, antibiótico, vitaminas, rayos X, prueba de sangre, ferritina, prueba de COVID) alcanza fácil los Q 3000 ($ 400). Es «poco» frente a otras enfermedades, pero para algunas personas sera la diferencia entre vivir o morir ante la ausencia del estado. Es bueno contar con una linea de crédito mínima o ahorros si te da COVID.

Síntomas y línea de tiempo de los 15 días de crisis

La caída de Tux

Poco menos de una semana después de ir al super, mi línea de tiempo fue la siguiente:

Día 1

Empecé con un dolor de cabeza extraño, soy una persona que no padece migrañas y de la nada sentí dolor de cabeza y un poco de debilidad. Una aspirina y a dormir.

Día 2

El dolor de cabeza continuaba, pero pasado el medio día me empecé a sentir muy mal y débil. Arranca la fiebre (37.9) que esa noche-madrugada llego a (38.6), con nauseas, dolor en todo el cuerpo. Diferente de una gripe normal, la fiebre llegó inmediatamente y fue aquí que supe que esto podía ser COVID.

Día 3

Luego de consultar con el doctor, me sugirió iniciar tratamiento preventivo con antiinflamatorios y antivirales, así como tratar de bajar mi fiebre. El doctor también me sugirió hacerme una prueba de sangre para buscar indicios o descartar COVID y tuve que ir por ella en moto ya que en Guatemala hay restricciones de circulación de vehículos, mis resultados demorarían dos días por la alta demanda en Guatemala. Nunca había manejado moto en este estado y debo decir que fue en lo mínimo, interesante.

Día 4

No fue un día muy diferente, febricula todo el día, falta de apetito y los antiinflamatorios empezaban a ayudarme junto con medicina para bajar la fiebre. Este día perdí el sentido del olfato.

Día 5 y 6

Empezaba a sentirme «mejor» pero me seguía poniendo cada vez más débil, luego de llamar como 10 veces a la linea del gobierno de Guatemala para el COVID y no obtener ninguna respuesta sabia que tenia que salir de esto por mi cuenta, la verdad no se ni porqué llame, el gobierno en mi país solo existe para robar.

Este día y siguiendo indicaciones médicas, cerré todas mis redes sociales, salir del COVID también es un proceso mental y no me ayudaba en nada leer noticias que si me llegaba a agravar tenia dos opciones: 1-Morir porque ya no hay hospitales públicos disponibles o 2- endeudarme por poco más de un cuarto millón de quetzales ($30,000) en un hospital privado.

Luego de ver mis exámenes de sangre el doctor me sugirió hacerme una prueba de COVID que no pude conseguir por medios públicos (porque simplemente no hay) y tuve que acudir a un centro privado pagando poco menos de $50 y hacer fila todo el día porque la crisis es real.

Acá descubrí que probablemente 50% o más de los resultados que el gobierno anuncia por sus medios son en realidad análisis en centros privados, todos están saturados.

Día 7

Este fue el peor día. Terminé el tratamiento preventivo de antiinflamatorios y llegó el resultado positivo para COVID-19.

El doctor me indicó que afortunadamente ya había iniciado el tratamiento y me indicó que debía monitorear constantemente mis signos vitales, especialmente oxigenación y temperatura.

Poco antes de intentar dormir la presión en el pecho empezó a aumentar y sentía una asfixia horrible, el aire me empezó a faltar y ya solo podía pensar que si necesitaban hospitalizarme no sabia que hacer, vivo solo y no sabia como pedir ayuda. Mi novia estuvo pendiente de mi toda la madrugada y la orden del doctor fue hacerme más exámenes inmediatamente.

Día 8

La falta de aire y presión en el pecho ya es constante y aumenta, en los rayos X efectivamente se empieza a ver la inflamación en los pulmones y empieza una neumonía por COVID por lo que es momento de iniciar un segundo tratamiento más agresivo basado en antibióticos y esperar que mi cuerpo reaccione.

Acá es importante señalar que es conveniente tener un oximetro ya que la sensación de asfixia se siente aunque no bajes de 90% de oxigenación, el número clave para decidir si te deben internar.

El «tratamiento» del COVID es ayudar al cuerpo contra los síntomas y esperar lo mejor.

Día 9, 10 y 11

De estos días sinceramente no recuerdo mucho, básicamente me concentraba en no morir. Cualquier esfuerzo mínimo me dejaba sin aire, cualquier posición para dormir era incomoda y tenia mucho sueño. Trataba de dormir, ver TV y pensar en cosas positivas. Las constantes fueron dolor de cabeza, diarrea, dolor de cuerpo, debilidad. Nunca me había enfermado así.

Estos son los días claves para saber si alguien necesitara ser hospitalizado y muchas personas buscan ayuda hasta este punto.

Día 12

Este día fue más o menos igual que los anteriores, solo que por fin empece a sentir que podía respirar un poco más, estas son buenas noticias.

Día 13, 14 y 15

Continué recuperando la respiración de a poquitos, cada día me siento un poco mejor y debo extremar medidas para cuidar mi salud. Finalmente paso de tratamiento con antibiótico a tratamiento con vitaminas.

La debilidad continua y perdí poco más de 10 libras, pero voy a vivir para contarlo.

Recomendaciones si te da COVID

A partir de esta experiencia mis recomendaciones serian las siguientes:

  • Mantener la calma: El angustiarse con el proceso agrava el sentimiento de asfixia y la mente es poderosa, especialmente en sentirse mal. Yo suelo ser una persona muy «realista» pero el distraerme ayudó en mi proceso para no caer en un hospital.
  • Comprar a tiempo un termometró y un oximetro: Serán los instrumentos vitales para un tratamiento en casa.
  • Definir una red de soporte y «cut the bullshit«: Lo que menos necesitas es gente cuestionandote, burlandose e incomodandote con sus preguntas o porqué no tomaste precauciones. Necesitaras una red de soporte para la alimentación, búsqueda de medicinas, especialmente porque las mismas están escasas (Guatemala tu nombre inmortal).
  • Apoyarte en la telemedicina: Ya sea que tengas un médico de cabecera o no, un paso previo es definir quien te dará seguimiento. Todos los tratamientos son experimentales en este punto y solo tratan la sintomatologia. Es vital contar con el seguimiento de un médico y no bancarse la enfermedad como una gripe normal. Un dato curioso es que el centro donde uno se realiza la prueba (CIAM en mi caso) te da una llamada gratis de seguimiento y también te hace SPAM para que puedas «adquirir» las teleconsultas con ellos.
  • Come frutas y verduras: Tu cuerpo va a necesitar mucha «gasolina» para salir de esto, nunca había comido tanta fruta en mi vida en tan poco tiempo pero fue necesario para salir.

Mi #MovedbyJava con fotos hasta 2020

En 2020 Java cumple 25 años, para celebrar el equipo de Oracle promovió el hashtag #MovedbyJava, mediante el cual las personas puedan compartir como Java ha impactado sus carreras e incluso sus vidas.

Mi jornada va más o menos así:

2006 – ¿Como aprendí Java?

Como estudiante de la Universidad de San Carlos llegué a la universidad en un periodo de cambio, donde el Ingeniero Armin Mazariegos reformó el pensum y cambió los lenguajes con los que se enseñaba en los cursos, promoviendo Java y .net como plataformas.

Los labs de la India, en su forma actual y con las compus de cuando aprendi Java 😅

Aunque la decisión le valió muchas criticas, lo cierto es que también consiguió un acuerdo con la embajada de India en Guatemala, específicamente para instalar el India-Guatemala IT Centre of Excellence conocidos como los laboratorios de la India.

En estos laboratorios tuve la oportunidad de recibir aproximadamente un año de capacitación con Java 5 y J2EE, las capacitaciones fueron exigentes a nivel de certificación. Con 18 años no sabia para que me serviría todo eso pero era divertido.

Hasta la fecha opino que el proyecto a nivel de números fue un fracaso, ya que a pesar de que la universidad es la más grande del país, los cursos originales (con instructores de India) los llevábamos en grupos pequeños de no más de 15 personas porque eran en ingles y fuera de horarios de clases. Una pena.

2006-2009 La comunidad de software libre

Mi tiempo libre durante la universidad lo invertía en comunidades de software libre, específicamente de Linux, en esta época Sun Microsystems era vista como una empresa benévola, y amiga del software libre, por lo que todos nos alegramos cuando liberaron el código de Java bajo GPL.

Entre otras cosas, varias personas iniciamos el Open Source University Meetup, una especie de grupo donde se promovían tecnologías abiertas como Java, Open Solaris y MySQL, todas en ese entonces bajo el brazo de Sun MicroSystems.

En esa época nos enviaban freebies:

2009-2011 – Mis primeros trabajos en Java

Aunque en la universidad experimenté muchos más lenguajes y plataformas (especialmente QT, Python y Ruby) lo cierto es que difícilmente hubiera encontrado trabajo con herramientas libres de no ser por Java.

El mundo de TI hoy en día no es el mismo que hace algunos años. Antes de la revolución de lenguajes y la apertura de transnacionales, en Guatemala era raro encontrar trabajo en algún lenguaje que no fuera parte de .net, de hecho solo conocí a una persona en la universidad que trabajaba en Java, mis tres primeros trabajos en Java fueron

  • Desarrollador freelance: Para la procuradoria de derechos humanos en Guatemala, acá tenían un sistema que era una mezcla de JSP, Struts y Faces
  • Desarrollador freelance: Para OpenTraining. Aca hice mucho desarrollo usando Struts, Faces y Linux :).
  • Desarrollador (y posteriormente Arquitecto) Java en Mobilges: En su tiempo la empresa se llamaba Soluciones Estrategicas, fue acá donde conocí Java en todas sus variantes ya que realizamos proyectos con J2ME (sobre BlackBerry), Java EE 5, Java SE 6 y 7. Hasta la fecha recuerdo con mucha estima este trabajo porque me permitió desarrollar mi potencial y NO ME OBLIGARON JAMAS A USAR TRAJE o camisa formal.
Frente del Case
Teletran 1, mi primer PC comprada con Java

2010 – GuateJUG

El grupo de usuarios Java de Guatemala -GuateJUG- es probablemente uno de los más antiguos en Centro América que aun siguen vigentes, a pesar de que inició en el 2007 en 2010 tuvo su «reinicio» al cual me uní para colaborar. Originalmente colaboraba solo como administración de sistemas, paginas y repositorios, pero el involucrarme en sus actividades cambió el rumbo de mi carrera:

Logo hecho por informaticos en 2010

2012-2014 – Mi beca en Brasil

El involucrarme en Open Source y difusión de conocimiento me abrió las puertas para vivir en Brasil. En este periodo de tiempo me dediqué a la investigación pura en ciencias de la computación y me aleje de Java para caer en . . . Scala, realmente nunca salí de la JVM.

Entre otras cosas pude presentar y asistir al Forum Internacional de Software Livre que en ese entonces era la segunda mayor conferencia de Software Libre en America Latina, acá entendí cual era el valor del networking y de las comunidades de software:

También acá conocí personas importantes de la comunidad Java que me ayudarían en los años venideros.

2014-2020 La comunidad Java Global

Luego de regresar a Guatemala y conocer a la comunidad global Java, poco antes del mundial de Brasil inicie a trabajar en Nabenik, originalmente nació como una empresa para brindar consultorías puntuales y ha ido creciendo a su propio ritmo.

Acá, también tuve la oportunidad de ir a mi primer Java One en Estados Unidos 2015. Recibí sponsorship de Oracle para el ingreso al evento en un programa de apoyo a los Java User Groups.

Lo más importante de conferencias como Java One no son las charlas (que de igual forma son de alto nivel) sino la calidad de networking que uno puede hacer en estos eventos. Por mi parte recibí apoyo de Nabenik para los costos del viaje y yo pagué algunos costos adicionales, la mejor inversión que he hecho en mi carrera hasta este momento.

En este punto conocí también a los integrantes de jespañol, con los cuales hemos hecho varias actividades en conjunto para promover Java en América Latina.

Luego de muchas actividades, certificaciones, viajes, clientes y un proyecto junto a GuateJUG con el cual recorrimos Guatemala enseñando Java, el vino a casa:

Mr, Duke, el mejor porta audifonos

Y eventualmente también esto pasó:

¿Fue mala idea aprender Java?, ni por un instante.

Le debo mucho a la comunidad Java por lo que ¡Vamos por los proximos 25 años!

Protegiendo aplicaciones con Payara Fish, MicroProfile JWT y OWASP Top 10

Esta es la grabación de una charla cuyo titulo original es «Seguridad en aplicaciones Java 101» aunque su enfoque (al menos en demo) es como proteger aplicaciones utilizando el OWASP Top 10

Durante la charla se explora la fundamentación teórica de la seguridad en Java y nos enfocamos en el OWASP Top Ten para Jakarta EE

Posteriormente hacemos una demostración de MicroProfile JWT con Payara Application Server

Por último explicamos como funciona un generador de Tokens JWT con acceso a los realms de usuarios en Payara Application Server

Como de costumbre, los slides se encuentran disponibles en Slideshare

El código fuente se encuentra disponible en GitHub

Introducción a Kotlin para Desarrolladores Java

El siguiente vídeo es la grabación en vivo de parte del workshop denominado «Introducción a Kotlin para Desarrolladores Java» como parte de los meetups del grupo de usuarios Java de Nicaragua

Durante la charla se explora Kotlin como un lenguaje de programación desde el punto de vista del desarrollador Java, ventajas, desventajas asi como bloques y expresiones propias del lenguaje.

Como de costumbre, la presentación se encuentra disponible en slideshare.