Herramientas de construccion de Java: ANT vs Maven


ACTUALIZACIÓN: Llegué a este artículo a través de un tweet de Kent Beek. Leelo bajo tu responsabilidad y lee los comentarios.
La mejor herramienta es la que has escrito tú. Cada proceso de construcción de un proyecto es único y a menudo los proyectos individuales necesitan ser construidos de diferentes maneras. Para los autores de estas herramientas es imposible anticiparse a cada requerimiento de construcción y temerario intentarlo (desarrolladores de Apache: tomad nota). Lo mejor que puede hacer cualquier herramienta es, proveer una libreria  flexible de tareas reutilizables, que se pueden adaptar fácilmente a tus necesidades, pero es insuficiente. Extraoficialmente las tareas nunca se adaptan a tu proyecto perfectamente. Perderás incontables horas luchando para hacer que estas tareas hagan lo que necesitas exactamente, solamente para darte por vencido y escribir un plugin en su lugar. Es rápido y fácil escribir tu propia herramienta de construcción personalizada, requiere menos mantenimiento del que temes. No te preocupes: las construcciones deberían ajustarse a tu proyecto, no al revés.
Si no quieres escribir tu propia herramienta, puedes usar Rake. Rake es la mejor herramienta de construcción para proyectos java. Proporciona un montón de métodos estándar para desarrollar las tareas de construcción más comunes, y cualquier cosa puede ser implementada rápidamente en Ruby. La gran ventaja de Rake sobre otras herramientas es que puede escribir scripts en un lenguaje de programacion real. Tiene otras ventajas, pero no son tan importantes.
De esta manera puedes escribir y personalizar herramientas de construcción para tus proyectos. Si no quieres puedes usar Rake. Si no quieres cambiar, deberías. Si la política impulsa las decisiones tecnológicas, si nunca te permitirán cambiar, entonces quedate en tu trabajo o deja el proyecto.
Si te falta coraje, entonces usa Ant. Ant es la segunda mejor herramienta de construcción existente para proyectos java. Es inferior a Rake, Ant sigue siendo una gran herramienta de construcción. Es maduro y estable, es rápido y viene con una rica librería de tareas. Hace posible script ricos (pero no todo es fácil), complejos procesos de construcción adaptados a las necesidades de tu proyecto.
Puedes escribir tu propia herramienta de construcción o cambiar a Rake, o pelear por cambiar a Rake, o irte a algún lugar donde puedas usar Rake. Y si todo esto falla, usa Ant hasta que puedas encontrar un nuevo trabajo donde se use Rake.
¡Eso es!, estas son las únicas que puedo recomendar, porque nunca, nunca, ¡bajo ninguna circunstancia uses Maven!.
Las construciones de Maven son una desesperacion infinita que lentamente te arrastrara al más profundo pozo de oscuridad del infierno (donde Maven fue forjada). Inicialmente tardaras 10 minutos en instalar y arrancar Maven, podrás ser feliz con él durante algún tiempo. Pero a medida que el proyecto evoluciona, y tu configuración de contruccion crece, el elemental pom.xml que iniciaste resultará inadecuado. Lentamente añadirás más configuraciones para trabajar con lo que necesitas, pero hay mucho que puedes configurar… (traductor: sigue hablando mal de Maven).
En serio, Maven es una implementación horrible de malas ideas. Creo que alguien en alguna lugar tenía (quizás todavia tiene) una visión de Maven que era razonable, sino seductora. Pero la actual implementación de Maven carece de cualquier vestigio de dicha vision. De hecho cada cosa en Maven está tan mal, que se sirve de ejemplos de como no hacer software.  Piensas que tu construcción es alucinante cuando funciona al revés que Maven.
Tenga en cuenta la salida de resultados de pruebas del plug-in Surefire de Maven. Todo parece bien cuando las pruebas se estan pasando, pero los informes de Surefire son una pesadilla para depurar cuando las cosas van mal. La única información conectada a la consola es el nombre del test que ha caído. Manualmente tienes que hacer una referencia cruzada con el nombre que se ha grabado en el fichero log, que se encuentra en el directorio target/surefire-reports, ¡pero estos logs estan escritos uno por test!, así que si fallan múltiples test, deberás separar múltiples ficheros logs. Parece una cosa menor, pero rápidamente será una molestia y hundirá la producción.
Los defensores de Maven reclaman que la herramienta cumple el Principio de la Convención sobre Configuración. Mienten. La única convención que soporta Maven es: compilar, ejecutar test unitarios, paquetes .jar. Usar Maven para hacerlo todo requiere configurar las convenciones. ¿Quieres empaquetar un fichero .war?, configúralo. ¿Quieres ejecutar tu aplicación desde la línea de comandos?, configúralo. ¿Quieres ejecutar test de aceptación o test funcionales o desarrollar test con tu ‘build’?, configúralo, esto implica no ejecutar los test unitarios, o no ejecutarlos mientras dura la fase convencional de test unitarios del proceso ‘build‘.  ¿Quieres generar un indicador del estado del código para tu proyecto? configúralo, pero los test se ejecutarán dos veces (o solamente una, pero no durante la ejecución normal de los test) y a veces informará de un estado de código de 0% a pesar del completo juego de test.
Hablando de confguración, Maven tiene la peor sintaxis de configuración desde Sendmail: alternando la forma normal XML. Como consecuencia, la configuración de Maven es abundante, difícil de leer y de escribir. Las cosas que puedes hacer en una o dos líneas de Ruby o XML con Rake o Ant requieren seis, siete u ocho líneas en la configuración del pom.xml (asumiendo que es posible hacerlo en Maven).
No hay nada coherente en la configuración de Maven. Algunas cosas son configuradas como ‘classpath references‘ (una referencia desde la ruta donde se encuentra la clase) hacia los ficheros ‘.properties’ construidos en ficheros ‘.jar‘ configurados como dependencias, algunas son configuradas como rutas absolutas o relativas de los ficheros en el disco y algunas son configuradas como propiedades del sistema en la JVM cuando se ejecuta Maven. Y algunas de estas rutas relativas son portadas a través de los proyectos porque Maven conoce como resolverlas correctamente, pero otras no. A veces Maven es lo suficientemente inteligente para construir recursivamente  proyectos en el orden correcto, pero a veces no.
¡Algunas cosas no son configuradas en el pom.xml!, como los repositorios Maven, los servidores, las credenciales de autentificación, que son configuradas en el fichero settings.xml. Es perfectamente razonable querer mantener el usuario y contraseña fuera del fichero pom.xml pues será comprobado dentro del repositorio de control de versiones del proyecto. Pero Maven tiene una solución terrible, toda la configuración está en el fichero settings.xml que vive fuera de cualquier directorio del proyecto. No puedes compartir directamente cualquiera de las configuraciones entre tu sobremesa y tu portátil, o con cualquier desarrollador, o con el servidor de tu proyecto. Pero es automáticamente compartido con cada proyecto único de Maven con el que trabajes y potencialmente con cada usuario que use el ordenador. Cuando un nuevo desarrollador se una a tu proyecto, deberá cambiar manualmente la configuración necesaria en el fichero settings.xml. Cuando un nuevo agente es añadido a tu granja de servidores, la configuración necesaria es manualmente fusionada en el settings.xml existente. Del mismo modo cuando quieras migrar a un nuevo ordenador. Y cuando cualquiera de estas configuraciones necesiten actualizarse, debe actualizarse manualmente en cada máquina. Esto estaba ya resuelto antes de que Maven llegase, también los archivos de propiedades. Los equipos de los proyectos pueden poner una configuración genérica como está en un fichero ‘properties‘ el cual es comprobado en el control de versiones y un desarrollador puede sobreescribir la información en el fichero ‘properties‘ local, el cual no está comprobado en el control de versiones.
Todas estas cosas en Maven -convenciones, configuraciones y procesos- son gobernados a la manera Maven. Desafortunadamente «la manera Maven» no esta documentada. Puedes encontrar algo fugaz buscando en la documentación de Maven, en Google, o comprando libros escritos por los desarrolladores de Maven. Otra manera de encontrar «la manera Maven» es tropezando con sus invisibles fronteras. Maven no fue creado para ser flexible y no soporta cada posible proceso de creación (‘build’). Fue creado para los proyectos de Apache, y asume todos los procesos espejos de construcción de proyectos de Apache como propios. Es una noticia genial para los desarrolladores open-source quienes voluntariamente en su propio tiempo entienden que liberar (‘release‘)  significa subir un fichero ‘.zip‘ a la web, para que otros manualmente lo encuentren, lo descarguen y lo añadan a sus propios proyectos. Es una faena para todo lo demas. Miestras Rake y Ant pueden acomodarse a cada proceso de construcción, Maven no. Es posible y muy probable que Maven no soporte la manera que tú tienes de construir tu software.
La gestión de dependecias que tiene Maven está completa, total e irrevocablemente rota. Actualmente, retiro lo dicho; la estrategia de Maven de descargar la biblioteca al directorio del usuario y volcarlo en el ‘classpath’ es increiblemente estúpido y equivocado y nunca debería ser confundido con «gestión de dependencias». Recientemente trabajé con Maven en un proyecto que produjo un fichero ‘.war‘ de 51MB; Cambiando a Ant, con gestión de dependencias, reducimos a menos de 17MB. Hmmmmm 51 -17 = 34 = 17*2 ó 2/3 del tamaño original.
Las dependencias extrañas no solo consumen espacio en disco, consumen también la preciosa RAM. Maven es un traga memoria. Relativamente, proyectos simples, con solo  un pom.xml y unos pocos submódulos requiere una extensa memoria de la JVM con todos las fantásticas opciones de JAVA_OPTS; esto sólo lo puedes ver en los servidores de producción. Las cosas empeoran si tu construcción Maven está integrada en tu IDE. Es muy común aumentar el tamaño de la memoria dinámica de la JVM a cientos de megabytes, el tamaño máximo ‘permgen‘ a unos pocos cientos de megabytes, permitir a ‘permgen‘ generalizar el recolector de basura de las clases. Todo esto para construir tu proyecto o para trabajar con Maven en tu IDE.
Una historia bonita: en ese mismo proyecto, Maven tardó diez minutos en hacer un ‘mvn clean‘ porque pensaba que necesitaba más basura «rm -rf ./target/«. Actualmente no hay ninguna bonita historia, créeme, no quieras contruir una herramienta que automaticamente descarga dependencias no resueltas antes de limpiar los directorios de construcción. Hace tus construciones no deterministicas [teoría que supone que la evolución de los fenómenos naturales está completamente determinada por las condiciones iniciales.]
Y todo innecesariamente, sobrecargando de red. Pagas una penalizacion en el rendimiento, Maven rompe la gestión de dependencias en cada construcción. 10 minutos para limpiar la construcción es horrible, pero añadir unos minutos extra para cada construcción es aún peor. Estimo que la sobrecarga promedio adicional de Maven es de aproximadamente un minuto por cada construcción, basado en el hecho de que la única vez que cambié Maven por Ant, la media del tiempo de construcción se redujo de dos minutos y medio a uno y medio. Similarmente, la vez que cambié de Ant a Maven el tiempo medio aumentó de dos minutos a tres.
No tienes el control, tienes poca visibilidad de lo que pasa dentro, las dependencias se especifican por tus dependencias. Los ‘builds‘ se romperán por las diferentes copias que Maven descargará de diferentes artefactos en diferentes momentos. Tu ‘build‘ local se romperá de nuevo en el futuro cuando las dependencias de tus dependecias acidentalmente lancen nuevas, no compatibles hacia atrás con los cambios, sin recordar poner el número de versión. Estos son fallos inocentes. El escenario más probable que es tu proyecto depende de versiones específicas de algún otro proyecto que tendrá dependencias de versiones antiguas de algún otro proyecto. Cada versión de cada dependencia será una nueva opotunidad para tirar muchas horas rastreando extraños fallos de construcción.
Pero Maven es incluso peor, no solamente resuelve automáticamente las dependencias de tu proyecto, también resuelve automáticamente las dependencias de sus plugins. Así que ahora no sólo tienes que preocuparte por las instancias independientes que Maven descarga accidentalmente de artefactos incompatibles (o que la misma instancia descarga artefactos incompatibles en diferentes momentos), también tienes que preocuparte de construir herramientas que se comporten de manera diferente a través de máquinas diferentes en momentos diferentes.
La mala gestión de dependencias de Maven también tiene un enorme agujero de seguridad, desde el cual actualmente es imposible determinar de donde provienen los artefactos y si han sido o no manipulados. Los artefactos tienen una suma de comprobación (‘checksum‘) automática cuando son subidos a un repositorio, Maven automáticamente verifica que la suma de comprobación cuando descarga el artefacto, pero implicitamente confía la suma de comprobación en el repositorio desde el cual se ha descargado. El alcance actual de la seguridad de los artefactos en Maven es que los desrrolladores de Maven controlan quién tiene acceso de escritura para el repositorio autorizado en la ibiblio. Pero no hay manera de saber si el repositorio del cual descargas todas tus dependencias está envenenado, no hay manera de conocer si la caché de tu repositorio local está envenenada, y no hay manera de conocer de donde proviene el repositorio de artefactos que está en tu caché local.
Estos problemas no son causados por desarrolladores temerarios, y no se solucionan usando un gestor de repositorios para bloquear todo artefacto que Maven necesite. Maven está arruinado y mal enfocado, y asume que los humanos nunca cometen errores. Maven está arruinado y mal enfocado si requieres que los usuarios explícitamente expecifiquen cada versión de cada dependencia, para reducir la probabilidad de descargarse artefactos incompatibles. Maven esta arruinado y mal enfocado si requiere una tercera herramienta para prevenir que se conecte y se descargue mierda. Maven esta arruinado y mal enfocado si piensa que no es lento descargarse cada ‘build conectándode a la red y comprobando cada dependencia de cada actualización y descargándolo automáticamente. Maven está arruinado y mal enfocado si se comporta de manera diferente en mi portátil de la oficina y en el de casa. Maven está arruinado y mal enfocado si requiere una conexión a internet para eliminar un directorio. Maven estáarruinado y mal enfocado.
Anuncio publicitario
Herramientas de construccion de Java: ANT vs Maven

13 comentarios en “Herramientas de construccion de Java: ANT vs Maven

    1. A estas alturas del partido podemos ver como queda en desuso ANT y MAVEN sige desarrollandose tanto que es un framework muy practico

  1. carlos dijo:

    Jose,
    No puedo estar mas en desacuerdo contigo.
    Maven es la mejor herramienta de construcción de proyectos en java. Y es INFINITAMENTE mas sencilla que ant. Si tienes un proyecto java medianamente complicado, un script ant puede ser ABSOLUTAMENTE diabólico de manejar.

    Si tienes una arquitectura bien montada para desarrollos java:
    * Un servidor de integración continua (Continuum o mejor Hudson)
    * Un servidor que haga de proxy para artefactos Maven (por ejemplo Archiva)
    * Un sonar (IMPRESCINDIBLE)
    * Selenium para test de navegación y de javascript.
    * Por supuesto un repositorio de código fuente (SVN,GIT)

    Este tipo de arquitecturas es sencillo echarlas a andar con Maven, con Ant SUDAS TINTA CHINA, y con Rake directamente no se puede.

    Además dices muchas cosas que no son del todo ciertas:

    Maven consume mucho espacio de disco… pues no. La gestión de librerías es la misma que la que puedas hacer tu, con la ventaja que te garantiza que en un equipo numeroso TODO EL MUNDO tiene las mismas, incluso puedes configurarlo para que se actualicen las releases automáticamente.

    Maven no sobrecarga la red si en tu infraestructura te instalas un repositorio que te haga de proxy (p.e. archiva)

    Si fijas la versión nunca se romperá un build.. Tienes ABSOLUTAMENTE TODO el control. Échale un ojo a un libro (el de sonatype «Maven: the definitive guide» no está nada mal)

    Por otro lado, échale un vistazo a http://openpario.mime.oregonstate.edu:3000/projects/archdevstack una serie de paquetes para la distribución archlinux. Conviene que para desarrollar te montes esa máquina virtual.

    Un abrazo y te veo en la próxima frikyquedada

    1. Muchas gracias por tu comentario. Porque ya me extrañaba a mi…
      Te has explicado perfectamente y me has ayudado a investigar mas cosas. Me has dado material.

      Nos vemos en esas y donde haga falta.
      Un fuerte abrazo

    2. Carlos, lo has dicho bien, exactamente lo que yo pienso:

      «Jose, No puedo estar mas en desacuerdo contigo.»

      En mi empresa hemos usado Ant por unos años antes de Maven y era un fiasco: nadie sabía como construir el proyecto cuando cambia el proyecto a que se dedica, era muy dificil cambiar cualquier cosa, lanzar nuevas versiones oficiales era dificil y propenso a hacer errores…un verdadero fiasco.

      Maven no es perfecto y seguramente no es facil para entender, pero funcciona en proyectos complejos (a diferencia de Ant y otras herramientas no declarativas), funcciona igual en todos nuestros Java proyectos, todos saben como construir el proyecto, donde va el codigo, los recursos, donde se especifican dependencias etc. Maven es modular

  2. @Nela dijo:

    Realmente me gusto mucho el debate aunque la verdad aun soy un novato en esto de gestores de tareas no les puedo aportar mucho pero basta mirar sus comentarios para poder investigar por mi cuenta !!!

    Saludos … tengo un blogger estoy preparando nuevos aportes aunque por el momento tengo solo uno !!! y me interesa la opinion de ustedes o de los que gusten echarle un vistazo … es de como instalar un ambiente de desarrollo en hardy heron (Ubuntu) de linux

    http://informaticabajocontrol.blogspot.com/

    Saludos

  3. David García dijo:

    No tienes ni pajolera idea de qué estás hablando. ¿Ant, Rake?. Nómbrame dos empresas que usen esas fantásticas tecnologías, según tú.

    Maven es la panacea:¿ sabes lo que es gestionar un equipo de 70-80 personas con ANT?. Un infierno, directamente.
    O no has trabajdo con maven o lo has hecho tan mal que te has convencido de lo que dices, pero no es cierto en absoluto.

  4. caramba, yo he usado maven por mas de 3 años y lo he llegado a encontrar muy práctico, ahora me veo en la necesidad de usar ant, del cual solo he tenido vistazos, buscaba convencerme de utilizarlo pero ahora ya no se :p

  5. phobox dijo:

    he intentado crear un proyecto ear(war,ejb,ws) con maven3 en eclipse y toca hacer unas 200 cosas para que funcione, de la forma tradicional lo hago en un par de minutos con todos los frameworks y librerias que quiera

    1. Victor Huerta dijo:

      pues si brother de la manera tradicional eclipse hace todo pero con maven no nesecitas mucho de eclipse solo debes saber configurar tu pom, y asi no ay problema si cambias de IDE o si programas con tu notepad

  6. Toni dijo:

    Me voy a arriesgar a que David me diga que no tengo ni p… idea, pero ahi va mi opinion.
    No he manejado maven, pero si ant y rake.
    Es verdad que, por lo que he leido en Internet, maven es muy facil si haces las cosas como dice maven. Pero, por otro lado, al ser su funcionamiento tan oscuro, cuando hay algun problema, su resolucion no es tan facil como lo es usando ant o rake.
    Rake es muy flexible y, al ser directamente ruby, si te hace falta alguna caracteristica, la programas y solucionado.
    La diferencia entre usar ant o rake y maven es, o tienes tu el control del build o lo tiene maven.
    Saludos

Los comentarios están cerrados.