Migrando de Ant a Maven
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