Migrando de Ant a Maven

sep 11, 2009 by Alfredo Casado

Hace tiempo que estamos detras de migrarnos de nuestro sistema de build actual: Ant a Maven. Para poneros un poco en situación se trata de un proyecto medio (54.000 lineas de código aprox) subdividido en varios modulos, unos 5 .jar con la logica y los API's del sistema y un par de aplicaciones web. Como se trata de un framework sobre el que desarrollar otras app's también tenemos varios proyectos a modo de ejemplos de uso de los distintos API's.

Motivos para el cambio

Esto nos suponia un cambio bastante gordo, tampoco se trata de tirarse a la piscina simplemente porque maven "mola más" o esta más de moda. Varios motivos han motivado este cambio:

  • Mantenimiento de los scripts de Ant: Cada vez nos costaba más y más mantener estos scripts. Cuando empezo el proyecto y eran pequeñitos todo perfecto, pero a medida que ha credido el proyectos los scripts también y con algún hack que otro que dificultaba cada vez su mantenimiento.
  • Mejorar la distribución de las librerías: Hasta ahora entregabamos nuestras librerías simplemente en un zip y a correr. Queriamos facilitar el trabajo de los usuarios de nuestra librería dejando las versiones liberadas en un repositorio, miramos Ivy también, pero maven nos parecia una solución más completa, y ya puestos a cambiar...
  • Facilitar la integración con otras herramientas: Usamos hudson como servidor de CI, y recietemente sonar para control de calidad. Estas herramientas se integran con ant pero su integración con maven es mucho más estrecha.
  • Soporte Multi-proyecto: Ant no tiene ningún tipo de soporte multi-proyecto, si tienes varios proyectos con ant y quieres tener una compilación autoamtica de todos en conjunto te lo tienes que montar "by hand" mediante ant-call o similares. En mi opinión cualquier sistema de build moderno debería tener soporte multi-proyecto con varios niveles (jerarquico) de forma nativa, que no todo son proyectos "hola mundo".

Nuestro ecosistema y maven

Es crucial que el sistema de build se integre en condiciones con el resto de herramientas de tu ecosistema, para nosotros era importante que se integrase bien con:

  • Netbeans: El soporte para maven en netbeans 6.7 ha sido un impulso grande para este cambio, el soporte es fantastico y nos permite seguir trabajando con nuestro IDE favorito y utilizar maven. Y aunque sea "ironico" el soporte de maven de netbeans también nos aporta la libertad de migrar a cualquier otro IDE que soporte maven (eclipse, JIdea) si fuera necesario, o que cada desarrollador use el que le de la gana.
  • Hudson: Nuestro amado hudson se integra con maven que da gusto. Si subes un proyecto multi-modulo con varios niveles de jerarquia te muestra una vista en árbol (bueno tabula un poco na más) de todos tus sub-modulos, indicando porque modulo va la compilación cuando esta activa. La verdad es que funciona increible hudson con maven, una pasada.
  • Sonar: Nos encanta sonar!, y aunque se puede usar en proyectos no-maven con maven todo es mucho más sencillo.
  • Subversion: Aunque en principio parezca que poco tiene quer ver con tu sistema de build, maven nos ha permitido no tener que guardar en svn todas las librerías de terceros que usamos (ahora están en el repositorio de maven, nexus en nuestro caso). Esto es importante si tienes 20 proyectos en tu empresa, cada uno con su propio svn, y en cada uno de ellos tienes que almacenar de nuevo todas las librerías de teceros y las compartidas entre los distintos proyectos de tu empresa.
  • Nexus: Junto con el uso de maven me parece imprescendible tener en la empresa montado un repositorio maven. Esto te permite no depender de los repositorios remotos, que no están bajo tu control y ¿quien te asegura que no casquen justo el día que te hacen más falta?. También te permite subir a el todas aquellas librerías que no están en los repositorios oficiles, tanto las de terceros que no se distribuyen via maven como las propias librerías que se generan en tu empresa y se comparten entre proyectos. De momento muy bien con nexus, instalación y configuración muy sencillas y 0 problemas, ya veremos claro, que llevamos una semana con el jeje.

Algunos plugins de maven interesantes

Existe una gran cantidad de plugins disponibles para maven, para casi cualquier cosa que te puedas imaginar que necesites en un sistema de build java tienes un plugin de maven que te facilita la tarea, esto ahorra mucho trabajo y sobre todo facilita luego el mantenimiento de los scripts si lo comparamos con Ant, algunos que nos han resultado muy utiles de momento:

  • Maven GWT plugin: Necesitabamos un plugin que nos ayudara con nuestros proyectos GWT, me ha sorprendido lo bien que funciona este plugin, en media mañana tenia los proyectos migrados de netbeans con GWT4nb a maven con el plugin de gwt. El único pequeño incoveniente es que a la hora de hacer debug con el hosted browser te ves obligado a ejecutar mvn gwt:debug y luego hacer attach a mano con el depurador de netbeans, pero creo que podre sobrevivir con esto :P.
  • Maven assembly plugin: Facilita muchisimo la tarea de crear distribuciones de tu proyecto. De momento hemos creado una distribución con jetty integrado, para que con doble click tengas un servidor de aplicaciones arrancado con tus app's montadas y una distribución de nuestras librerías empaquetada en un simple zip (junto con las dependencias de terceros, documentación y código con ejemplos de uso del API), para los usuarios que no usen maven sigue siendo necesario este modo de distribución, a nosotros nos gusta maven pero no podemos obligar a todo el mundo a trabajar como a nosotros nos guste :P
  • Maven ant-run: Quizas ant no sea lo mejor para montar un build muy complejo, pero para pequeñas tareas de copiar ficheros de un lado para otro y cosas de este estilo sigue siendo una herramienta util. Algo que a muchos no les gusta de maven es su rigidez, sin embargo con este plugin tienes la facilidad de la "convención sobre configuración" que ofrece maven y la flexibilidad de ant cuando sea necesaria. En pequeñas dosis puede ser un plugin muy util.
  • maven sonar plugin: El solito te hace un analisis de tu proyecto utilizando findbugs, checkstyle, pmd, cobertura... y inserta los resultados en la bd de sonar para luego poder consultarlos desde la UI web. Esto mismo con ant lo haciamos con un buen puñado de scripts, y con maven es un simple comando. De todos modos ni siquiera lo usamos directamente, hudson cuenta con un plugin para sonar que te permite activar el analisis sonar despues de cada compilación, más facil y mejor integrado imposible.

Además de estos hemos usado algún otro como el plugin javadoc y el plugin sources para incluir los fuentes y el javadoc al lado de los .jar que distribuimos via repositorio maven, el plugin maven dependency para copiar dependencias en la distribución y se me estará olvidando alguna más seguro...

Nuestra jerarquia de proyectos

En un proyecto complejo, con varios modulos, al final lo que acabas teniendo es una jerarquia de sub-modulos, esto es algo que me encanta de maven, que soporta este tipo de proyectos de forma muy sencilla, la nuestra es más o menos así:

  • Proyecto Principal
    • Api's
      • API 1
      • API 2
      • API 3
      • API 4
      • API 5
    • Ejemplos Api's
      • Ejemplo 1
      • Ejemplo 2
      • Ejemplo 3
    • Aplicaciones
      • App Web 1
      • App Web 2
    • Distribuciones
      • Distribución Con Jetty integrado
      • Distribución de API's con librerías de terceros incluidas
      • Distribución en formato EAR

Es complicadillo, lo bueno es que con maven resulta muy natural motar algo así, y utilizando la herencia en los POM's puedes poner cada cosa en su sitio sin tener que duplicar las dependencias en cada pom. Por ejemplo, las aplicaciones dependen los los API's, con lo que las dependencias no están definidas en cada aplicación sino en el pom de "Aplicaciones", esto es utilisimo para mantener el build manejable y las cosas en un solo sitio. O por ejemplo puedes cambiar en el super-pom la versión del jdbc de mysql, ejecutar el build desde arriba, y si todos tus test pasan sabes en 5 minutos que tu aplicación funciona con la nueva versión, espectacular!.

Conclusiones

Pues de momento muy buenas, pensaba que iba a ser un cambio mucho más complejo y en menos de una semana hemos montado todo el tinglao sin mucho problema. Quitando algún tema con el encoding, alguna chorradilla con los classpath de ejecución y poco más, y más bien por nuestro desconocimiento que por culpa de la herramienta. Cuando llevemos unos meses así ya os contaré a ver si mi opinión sobre maven sigue siendo tan positiva como hasta ahora jeje.

El único problema "serio" que tenemos hasta ahora es con los analisis de cobertura, tenemos un proyecto de test funcionales donde metemos pruebas de aceptación y sistema, es decir, pruebas que afectan a código que esta en otros modulos. El problema es que el plugin de cobertura no computa esta cobertura junto con la del resto (la de las pruebas unitarias de cada proyecto) con lo que en el informe final de cobertura perdemos el porcentaje correspondiente a los test funcionales. Con lo que pasamos de un casi 70% de cobertura en los api's a algo menos de 50%. Ya os contare cuando encontremos una solución para esto. Pero vamos, si este es nuestro mayor problema... es que la cosa no va mal jeje



Comentarios:

Hola Alfredo,
gracias por tu experiencia pq estoy pensando justo en hacer lo mismo que has hecho.
Lo que me está moviendo a Maven es poder usar Sonar y que se pueda usar Maven en NetBeans sin problemas.

Lo que no me queda claro del todo es que pinta "Nexus". ¿Es como tu dices para tener la librerías que de otra forma te tendrías que bajar de Inet? O es para guardar todos los binarios que no están en SVN.

Saludos.

Enviado por logongas en septiembre 11, 2009 a las 08:29 PM GMT+01:00 #

Hola logongas, nexus cumple varias funciones en realidad:

- Servir de proxy/cache de las librerías que están en inet.

- Los build son repetibles con tu propia infraestructura, sin depender de eventuales caidas de los servidores de inet.

- Almacenar librerías de terceros que no están en inet. Las subes a tu propio repositorio y listo.

- Publicar las propias librerías que tu generas. Facilitando mucho la distribución de librerías entre equipos de la misma organización.

En mi opinión para una organización que use maven es fundamental un repo de artefactos, para usarlo yo en mi casa tampoco me liaria tanto eso si.

Enviado por 83.53.97.13 en septiembre 11, 2009 a las 09:39 PM GMT+01:00 #

Buen resumen!

No te olvides de la ventaja de tener por fin una única manera de hacer las cosas! Se acabó el estudiarse para cada proyecto la estructura de carpetas y el script de build.

Para mi lo que más cuesta es cambiar el chip en la gestión de dependencias. Pero una vez te adaptas todo son ventajas.

Sobre el repositorio, exactamente como comentas. En un equipo es imprescindible, sobretodo para que el programador medio no se atasque con las librerias de 3os, ya que pej los drivers de jdbc no suelen estar en los repositorio publicos. Pero para trabajar de forma individual es innecesario.

Un saludo y no te olvides de contarnos si resuelves lo de la cobertura, yo tengo un problema parecido: quiero calcular la cobertura que tienen mis tests selenium ejecutados sobre la aplicacion desplegada en un servidor remoto.

Enviado por jcesarperez en septiembre 12, 2009 a las 12:31 PM GMT+01:00 #

Son tantas ventajas que alguna se me olvida xd, lo que comentas de la estandarización en la forma de los proyectos es otro punto importantisimo. Y la dependencia transitiva de dependencias otra cosa que no comente muy importante.

También esta el tema de los arquetipos, nos vienen fenomenal ya que nuestro desarrollo es un framework que luego se extiende con plugins o aplicaciones que se ejcutan sobre las librerías base, proporcionar esqueletos para estas extensiones con todo preparado en un buen ahorro de tiempo también.

el tema de la cobertura tiene más tela de lo que pensaba, en sonar tienen algunos tickets relacionados con el tema:

http://jira.codehaus.org/browse/SONARPLUGINS-138
http://jira.codehaus.org/browse/SONAR-613

Tengo que investigar más sobre el tema.

Enviado por Alfredo Casado en septiembre 12, 2009 a las 01:21 PM GMT+01:00 #

Hola Alfredo

excelente resumen sobre maven, en mi empresa tenemos montado exactamente el mismo ecosistema, ya llevamos mas de dos meses con el y solo decir que ha funcionado perfecto. La unica diferencia es que nosotros no migramos de ningun ant, simplemente los proyectos nuevos los empezamos con maven y al "framework" de abstraccion que usamos simplemente creamos nueva version mucho mejor y sin compatibilidad hacia atras xD

continua--

Enviado por Marioko en septiembre 12, 2009 a las 02:04 PM GMT+01:00 #

Lo unico extraño que he visto es que cuando utilizas el plugin de Hudson para netbeans y le dices que configure algun proyecto nuevo en el server hudson utiliza algo diferente (todavia no se que es) que hace que cuando se compile un pom padre solo se cargan/verifican los archivos de subversion y listo. Los proyectos hijos entonces empiezan a compilarse de la forma "si yo dependo de xyz pom y a ese lo acaban de compilar entonces yo me compilo". Hasta alli todo bien el problema es que me han salido extraños errores de compilacion en esos casos. La solucion configurar directamente en el server hudson el proyecto y NO usar el plugin de netbeans.

Saludos y te felicito por tu blog, estos dias he andado leyendolo y he aprendido un monton de cosas!!

-fin-

Enviado por Marioko en septiembre 12, 2009 a las 02:04 PM GMT+01:00 #

Hola marioko,

A mi me paso lo mismo con huson y netbeans, lo que ocurre es que los proyectos que crea netbeans en hudson llevan marcada la opción "build modules in pararell" (o algo muy similar), que no he investigado mucho pero en nuestro caso también provocaba errores raros de compilación.

Los puedes crear desde netbeans pero te tienes que acordar de desactivar la dichosa opción, que esta justo debajo de donde le dices la ruta del pom pulsando en "advanced" (encima la esconden xd).

Enviado por Alfredo Casado en septiembre 12, 2009 a las 02:15 PM GMT+01:00 #

je gracias, si lo esconden es por algo, depronto todavia es experimental o tiene bugs!

De todas formas tener varios proyectos compilandose en paralelo puede dejar frito al servidor de hudson que por cierto consume bastante memoria.

Enviado por Marioko en septiembre 12, 2009 a las 04:19 PM GMT+01:00 #

Gracias Alfredo por la aclaración de Nexus.

Enviado por Logongas en septiembre 13, 2009 a las 07:24 PM GMT+01:00 #

Hola Alfredo he leido tu experiencia sobre la migración de Ant a Maven, nosotros también teníamos pensado hacer lo mismo, una consulta que quería hacerte es si seguiste algún manual en concreto, algún sitio donde explique los pasos que hay que hacer para migrar de manera correcta un proyecto Ant a Maven respetando la estructura creada por el primero.

Lo mucho que he podido encontrar hasta el momento es un ejemplo en el libro de Maven en el que muestra un ejemplo de migrar un proyecto en Spring a Maven pero poquito más.

Te lo agradecería mucho la ayuda aporta

Un saludo

Mario

Enviado por Mario en marzo 05, 2010 a las 09:38 AM GMT+01:00 #

Enviar un comentario:
  • Sintaxis HTML: Deshabilitado