Maven contra Ant: Migrar nunca ha sido fácil
En estos momentos estoy comenzando un proyecto para la compañía en la cual trabajo el cual consiste en mejorar la forma en como liberamos el código de nuestra aplicación en producción; Sin entrar en muchos detalles les puedo decir que estoy re-escribiendo el sistema de compilación que fué creado con Ant + Make en Maven.
El proyecto ha tenido sus dificultades (menores) y la curva de aprendizaje en mi caso no fué trivial ya que uno de los problemas que quería resolver es como compartir dependencias (archivos jar o ‘artefactos’) entre ellos:
- Ant es declarativo. En Ant todos las acciones se especifican con mucho nivel de detalle, pero esto se hace tedioso especialmente cuando los proyectos son grandes o hay muchos proyectos (repetir una y otra vez). Makefile fué usado para manejar las dependencias entre proyectos de código nativo en C y luego para unir llamadas a Ant. Un desastre
- Soporte para Eclipse, InteliJ: Debido a la forma en la compilación con Ant fué escrita, no se puede compilar en Windows de la misma manera que Linux. Muerta la portabilidad, además de que cada desarollador tenia que aprender ciertos trucos para poder compilar la aplicación en Linux.
Al principio traté de resolver el manejo de las dependencias en Ant usando Ivy. Pero la documentación de Ivy es espantosa y por irónico que parezca hace muchas referencias a Maven. Especialmente estoy último terminó por decidirme a usar Maven, convención sobre configuración, buen soporte especialmente en Eclipse e InteliJ.
No pienso escribir un tutorial sobre Ant contra Maven (Google les puede mostrar cientos de ellos), pero las comparaciones son obvias, miren por ejemplo como se compila a StupidZombie.com:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | < ?xml version="1.0"?> <project name="StupidZombie" default="jar" basedir="."> <description> StupidZombie is a program that allows you to ping several of your favorite Blog directories. The idea is to avoid fill the same information over and over again. StupidZombie es un programa el cual le permite hacer ping a varios de sus directorios de Blogs favoritos. La idea es evitar rellenar la misma información una y otra vez. </description> <property file="build.properties"/> <path id="path.classpath"> <pathelement location="${jar.xmlrpc-client}"/> <pathelement location="${ar.ws-commons-util}"/> <pathelement location="${jar.xmlrpc-common}"/> <pathelement location="${jar.codec}"/> <pathelement location="${jar.tidy}"/> <pathelement location="${jar.httpclient}"/> <pathelement location="${jar.net}"/> <pathelement location="${jar.log}"/> </path> <path id="path.test"> <path refid="path.classpath"/> <pathelement location="${jar.junit}"/> <pathelement location="${build}"/> <pathelement location="${test}"/> </path> <target name="build" depends="init" description="Compile the source code"> <javac srcdir="${src}" destdir="${build}" deprecation="true" optimize="false" debug="true"> <include name="**/*.java"/> <classpath refid="path.classpath"/> </javac> <copy description="Copy the resourcebundles for all the classes" todir="${build}" overwrite="true"> <fileset dir="${src}"> <include name="**/*.xml"/> </fileset> <fileset dir="${res}"> <include name="**/*.properties"/> </fileset> </copy> </target> <target name="init" description="Pre compilation tasks"> <mkdir dir="${dist}"/> <mkdir dir="${build}"/> <mkdir dir="${test}"/> </target> <target name="clean" description="Artifact cleanup"> <delete includeEmptyDirs="yes" failonerror="no"> <fileset dir="${build}"/> <fileset dir="${dist}" /> <fileset dir="${test}" /> </delete> </target> <target name="jar" <target name="jar" depends="build" description="Pack the project sources for distribution"> <manifest file="${jar.file.manifest}"> <attribute name="Main-class" value="com.stupidzombie.gui.StupidZombieGui"/> </manifest> <copy description="Copy the images for the app" todir="${build}" overwrite="true"> <fileset dir="${img}"> <include name="**/*"/> </fileset> </copy> <unjar src="${jar.xmlrpc-client}" dest="${build}"/> <unjar src="${jar.ws-commons-util}" dest="${build}"/> <unjar src="${jar.xmlrpc-common}" dest="${build}"/> <unjar src="${jar.codec}" dest="${build}"/> <unjar src="${jar.httpclient}" dest="${build}"/> <unjar src="${jar.tidy}" dest="${build}"/> <unjar src="${jar.log}" dest="${build}"/> <jar jarfile="${dist}/${jar.project}" basedir="${build}" manifest="${jar.file.manifest}"> <exclude name="**/test/*"/> </jar> <signjar jar="${dist}/${jar.project}" alias="StupidZombie" keystore="StupidZombie.keystore" storepass="StupidZombie" verbose="false" /> </target> <target name="test" depends="jar" description="Unit tests"> <echo>Running unit tests</echo> <javac srcdir="${src}" destdir="${test}" includes="com/stupidzombie/ping/**/Test*" deprecation="true" optimize="false" debug="true"> <classpath refid="path.test"/> </javac> <junit fork="yes" printsummary="on" maxmemory="300m"> <classpath refid="path.test"/> <formatter type="xml" /> <formatter type="plain" /> <sysproperty key="ping.blog.name" value="StupidZombie"/> <sysproperty key="ping.blog.url" value="http://stupidzombie.com/blog"/> <sysproperty key="ping.blog.directoryList" value="technorati"/> <test name="${testcase}" todir="${test}" if="testcase"/> <batchtest </batchtest> </batchtest></junit> <junitreport todir="${test}"> <fileset dir="${test}"> <include name="TEST-*.xml"/> </fileset> <report format="frames" todir="${test}"/> </junitreport> </target> </project> |
Además de tener que guardar los archivos Jar en SVN (mala practica) el archivo de compilación es grande.
Mientras que en Maven:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | < ?xml version="1.0"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupid>com.stupidzombie</groupid> <artifactid>stupidzombie</artifactid> <version>20120206</version> </parent> <modelversion>4.0.0</modelversion> <artifactid>ping</artifactid> <packaging>jar</packaging> <name>ping</name> <build> <plugins> <plugin> <groupid>org.apache.maven.plugins</groupid> <artifactid>maven-jar-plugin</artifactid> <configuration> <archive> <manifestfile>src/main/resources/META-INF/MANIFEST.MF</manifestfile> </archive> </configuration> </plugin> <plugin> <artifactid>maven-assembly-plugin</artifactid> <configuration> <descriptors> <descriptor>src/assemble/bigjar.xml</descriptor> </descriptors> <archive> <manifestfile>src/main/resources/META-INF/MANIFEST.MF</manifestfile> </archive> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupid>org.apache.xmlrpc</groupid> <artifactid>xmlrpc-client</artifactid> <version>3.1.2</version> </dependency> <dependency> <groupid>ws-commons-util</groupid> <artifactid>ws-commons-util</artifactid> <version>1.0.1</version> <scope>compile</scope> </dependency> <dependency> <groupid>commons-codec</groupid> <artifactid>commons-codec</artifactid> <version>1.3</version> <scope>compile</scope> </dependency> <dependency> <groupid>commons-httpclient</groupid> <artifactid>commons-httpclient</artifactid> <version>3.1</version> <scope>compile</scope> </dependency> <dependency> <groupid>commons-net</groupid> <artifactid>commons-net</artifactid> <version>2.0</version> <scope>compile</scope> </dependency> <dependency> <groupid>jtidy</groupid> <artifactid>jtidy</artifactid> <version>4aug2000r7-dev</version> </dependency> </dependencies> </project> |
Mi migración a Maven no estuvo libre de dolores:
Aún tengo muchas preguntas en Maven, como por ejemplo el uso de perfiles y de ‘snapshots‘. Sin embargo ya logré colocar los artefactos de mis proyectos con buen manejo de versiones y para quienes lo desean en mi grupo, pueden trabajar con M2E en Eclipse.
Mucha gente habla maravillas de Gradle, sin embargo me parece que no tiene tanta tracción como Maven, soporte básico para Eclipse, además de que hay que aprender algo de GROOVY (no es necesariamente algo malo). ¿Alguno de ustedes ha tenido experiencia real con este entorno?




Comentarios recientes