Editar, Guardar y Recargar en Java
Después de bastante tiempo programando únicamente en Python y Django, hace año y medio cambié de trabajo. Desde entonces he vuelto a programar en Java, desarrollando aplicaciones y servicios web, así como coordinando a un equipo de programadores web.
Pronto me di cuenta de que el equipo seguía el siguiente ciclo a la hora de desarrollar:
- Hacer cambio.
- Compilar un WAR.
- Copiar el WAR al servidor Tomcat local.
- Reiniciar el servidor.
- Iniciar una sesión de debug desde Eclipse.
- Probar.
Esto hacia que cada prueba supusiera, en el mejor de los casos, esperar 5 minutos desde que se hacia un cambio hasta que este se podía probar. Lo cual nos dejaba con una productividad, digamos que mejorable.
Desde entonces, hemos mejorado el entorno de desarrollo, de forma que ahora podemos modificar el código fuente Java en caliente e inmediatamente ver y depurar los cambios, sin necesidad de recompilar y recargar toda la aplicación, consiguiendo un flujo de trabajo más parecido al de Django o PHP.
El "secreto" (entre comillas, por que está más que descubierto) se basa en tener el servidor de aplicaciones empotrado, de modo que este pueda arrancarse como un programa Java en modo debug, desde Eclipse. De esta manera conseguimos que desarrollar una aplicación web sea, a efectos del flujo de trabajo, como programar una aplicación Java "local", pudiendo aprovechar toda las herramientas que pone a nuestra disposición el IDE, como la compilación automática y el cambio en caliente del las clases compiladas.
Las únicas limitaciones del cambio en caliente son las propias de la especificación JPDA. Esto es, la actualización en caliente solo funciona mientras se modifique el cuerpo de las funciones. Cualquier modificación en los parámetros de un método o en la definición de una clase nos obligará a reiniciar el servidor (aunque no tendremos que recompilar nada).
En la actualidad, usamos como servidor empotrado Jetty, a través del plugin de Eclipse run-jetty-run.
A la hora de usar Run-Jetty-Run tuvimos que resolver 2 problemas:
- El plugin no soporta JNDI de serie, aunque aplicando este pequeño parche se soluciona.
- A los usuarios de Windows, Jetty les bloqueaba los ficheros estáticos (por ejemplo css o javascript) de modo que no podían modificaros mientras el servidor estuviera en marcha (gran problema). Quedó solucionado siguiendo las instrucciones de este ticket.
Únicamente en un proyecto, de características muy especiales, Jetty no fue capaz de ejecutar una aplicación. En este caso, tuvimos que usar un Tomcat empotrado. Gracias al código fuente y las instrucciones de un artículo en onJava, no tuvimos ningún problema en ejecutar un Tomcat desde Eclipse, consiguiendo el mismo efecto que con Jetty.
¿Por que usamos Jetty en lugar de Tomcat? Principalmente por que run-jetty-run es más fácil de configurar y está muy bien integrado con Eclipse. Ademas Jetty arranca casi de inmediato.
Si tu flujo de desarrollo en Java se parece al que he descrito al inicio de esta entrada, te aseguro que vale la pena que inviertas algo de tiempo en mejorarlo. No es difícil, y los beneficios son considerables.