En grandes proyectos de desarrollo es habitual que se produzcan largos períodos de tiempo en que los programadores físicamente no pueden trabajar, ya que el código está compilándose. Este problema es conocido e incluso se pueden encontrar chistes al respecto.
Estos períodos son tiempo perdido ya que, aunque el programador podría seguir trabajando, hay un alto riesgo de que la compilación haya detectado algún problema 10 minutos después.
Para evitarlo, hay varias cosas que se pueden hacer: desde mejorar nuestros procesos hasta usar herramientas que limiten la necesidad de compilar tan a menudo. Vamos a centrarnos en el mundo de Java, aunque puede extenderse a otros lenguajes.
La compilación en Java
En Java, la compilación ya no se hace a mano sino con un builder como Maven, Ant o Gradle. Estas herramientas no solo compilan, sino que también ejecutan pruebas, empaquetan o realizan otra serie de tareas que tal vez no necesitemos. Concretamente, Maven ejecuta dos ciclos de vida, dos compilaciones distintas: clean), que borra todos los ficheros producidos por un build anterior; e install), que genera código, lo compila, ejecuta tests, crea los JAR, los copia a nuestro repositorio de librerías… Muchos de estos pasos no aportan valor en tiempo de desarrollo, por lo que lo primero que podemos hacer es usar el comando adecuado en cada momento, normalmente “mvn clean compile” es suficiente.
Por supuesto, si sólo lanzamos este comando, los tests no se ejecutan y no sabremos si estamos introduciendo problemas en el código. Afortunadamente, cualquier IDE, como por ejemplo Eclipse, es capaz de ejecutar esos tests de manera aislada, ¡pues hazlo! No esperes a que Maven ejecute toda la batería de pruebas para saber si has roto algo.
Presta atención a los plugins. Maven se basa en plugins. En nuestra configuración puede haber plugins automatizados dentro del ciclo de vida, posiblemente haciendo que el build sea más largo de lo necesario. Esto se puede evitar si en lugar de ejecutar «mvn compile» ejecutamos «mvn compile:compile».
Hoy en día, todos los proyectos se componen de múltiples módulos. Otra forma de ahorrar tiempo es compilar sólo los módulos modificados. Correcto, pero ahora perdemos los tests de integración que verifican que dos módulos se comportan bien juntos: ejecuta el test adecuado en el momento adecuado. Los tests de integración, regresión, end-to-end, etc., no están pensados para cada pequeño cambio de código. Cada test está pensado para una fase del ciclo de desarrollo. Concretamente, los test de integración tienen sentido en Integración Continua (CI) y Despliegue Continuo (CD). ¡Ejecútalos entonces!
Es lógico querer probar tu aplicación simulando el entorno de producción, por ejemplo con WebLogic, y se puede hacer, pero desplegar una aplicación en WebLogic es más lento que hacerlo en Tomcat o JBOSS. Además, se puede integrar el servidor en el IDE para que el despliegue sea automático.
En casos muy particulares, muy controlados, sabiendo lo que se hace, para testear en servidor local, es posible ganar tiempo si obviamos los tests al desplegar con, por ejemplo, Cargo, añadiendo un parámetro –DskipTests a nuestro Maven.
No sólo Maven
Hemos hablado mucho de Maven pero hay alternativas. Maven no es para ejecutar builds a menudo, o cuando queremos personalizarlo. Gradle por ejemplo, permite crear diferentes ciclos de build basados en grafos, por lo que pueden ejecutarse de manera incremental, esto es, aquellos módulos que no han cambiado no necesitan volverse a compilar, ahorrando mucho tiempo.
Una vez hemos puesto en práctica todas estas recomendaciones, todavía podemos mejorar mediante máquinas virtuales auto actualizables (Java obliga a reiniciar la máquina para cargar los cambios). Existen alternativas como JRebel o DCEVM que carga automáticamente las nuevas clases en la máquina, si hace falta.
En todo caso, analiza bien lo que haces, puede que las necesidades, las interfaces con otros servicios, etc, no estén bien definidas o que el diseño de la solución no sea correcto. En estos casos, introducir una herramienta como JRebel sólo va a tapar momentáneamente el problema y puede que vuelva a aparecer.