martes, 9 de febrero de 2010

Desarrollo en equipo con SVN, Maven y Nexus (parte I)

Banco de experiencias (V)


El orden es el placer de la razón pero el desorden es la delicia de la imaginación.
-Paul Claudel.

El desarrollo de software aúna una fascinante mezcla de pensamiento divergente (o creativo) con conceptos técnicos y prácticas metódicas. Para que un desarrollador (y especialmente un equipo de desarrollo) alcance los mayores niveles de eficiencia y productividad, las herramientas utilizadas deben garantizar la seguridad del proceso, pero siempre de forma proporcional a la envergadura del proyecto y manteniendo compatibilidad con el proceso creativo sin ahogarlo. Hay herramientas libres que nos ayudan a mantener este este delicado equilibrio entre orden y libertad para todo tipo de proyectos de forma sencilla e impecable.

Éste, como el resto de los artículos de la serie "banco de experiencias", no pretende ser un artículo más de documentación sobre las herramientas aquí comentadas ni encontrarás tampoco el enésimo tutorial sobre el asunto. Hay mucha documentación en la red y a lo largo del artículo suelo ofrecer información y referencias suficientes para que puedas profundizar en el tema. La idea de estos artículos es exponer buenas prácticas y comentar mi punto de vista, basado en mi propia experiencia profesional, sobre la utilidad real y pragmática de los temas abordados. Sin demagogia rimbombante ni publicidad interesada. Simplemente la síntesis de mi experiencia subjetiva.

Subversion

Subversion (también conocido simplemente como svn) es probablemente el mejor sistema de control de versiones centralizado que existe. Sin entrar en la discusión Centralizado vs Distribuido (DVCS), lo que si está claro es que el control de versionado es un aspecto crítico de cualquier proyecto de software.

En todo caso, si has llegado hasta aquí y no has usado nunca un software de control de versionado (VCS) la recomendación es clara: úsalo. Debes usarlo. Aunque tu proyecto sea muy pequeño. Aunque sólo exista un desarrollador. Has de asumir que, de la misma forma y con la misma naturalidad que usas un IDE o un compilador, deberás usar un VCS. Es absolutamente esencial. Si ya tienes claro que hay que usar uno y has decidido usar uno centralizado (o simplemente sueles usar otro, como CVS, por ejemplo), la recomendación también es clara: usa svn. En la wikipedia puedes consultar por qué SourceForge.net, Apache o Google Code lo eligieron, así como la documentación y herramientas disponibles.

Como decía, un software de control de versiones es necesario aunque el proyecto sea pequeño ya que te garantiza un seguimiento de cambios que te puede ahorrar muchas horas de trabajo. Si tienes clara la diferencia entre un editor de texto y un procesador de texto, entenderás enseguida la diferencia de usar backups de tu directorio de código y usar un VCS. No obstante, hay otro aspecto importante de los VCS que no suele ser tan comentado (quizá por obvio) y es su dimensión como herramienta colaborativa. Si de forma individual es extremadamente importante, para un equipo es absolutamente imprescindible. Un equipo no puede trabajar de forma "decente" sin Subversion. La idea de no usar un VCS o de usar uno bloqueante (tipo Visual SourceSafe) es una pesadilla para no dormir: "¡eh, cuidado!, no toquéis que voy a tocar yo" "¡Oh, mierda!, ya ha tocado alguien. ¡A ver ahora cómo lo arreglamos!"... o "¡fulanito, desbloquea el fichero que necesito añadir un método de la clase!" "¡No, espera que termine!"... Qué pesadilla. Me recuerda a aquellas herencias arcaicas de los programas COBOL de no pasarte de la columna 73 y poner los asteriscos en la columna nº 7... Bufff.

Trabajar con svn en equipo es lo más parecido a hacerlo como si estuvieses tú sólo. Si las tareas están repartidas, los conflictos son muy poco frecuentes (para que existan, dos desarrolladores deben haber modificado la misma línea simultáneamente antes del último commit) y cuando los hay, se suelen solucionar en pocos segundos. Es muy gratificante comprobar cómo un equipo numeroso puede trabajar en una aplicacion Web (un tipo de proyecto con un alto grado de colisión y concentración de trabajo) de forma cómoda y fluida sin problemas.

Maven

Aunque llevamos oyendo hablar de Maven desde hace varios años (Maven tiene ya 8 años), la adopción hasta hace cuatro o cinco años ha sido puntual y conceptual. Es desde la aparición de Maven2 (con su nueva arquitectura revisada) cuando realmente empieza a incorporarse (aunque también de forma muy lenta) a los distintos proyectos open source y esto ha hecho que en la comunidad de desarrollo comencemos a interesarnos y a integrarlo en nuestros proyectos. A mucha gente le ocurre que, tras leer sobre Maven y Ant, entiende las diferencias entre ellas, pero no alcanza a concretar por qué es tan importante y para qué le sirve realmente (qué le aporta que no tenga ya). Para aclarar definitivamente este punto simplemente hay que preguntarse cómo realizamos el proceso de construcción (generación de empaquetados y otros artefactos) en nuestros proyectos, y esto nos dará la respuesta. Veamos las opciones:
  1. Construimos con nuestra herramienta de desarrollo (Eclipse, Netbeans, etc...).
  2. Construimos con un fichero (build.xml) ant que nos hemos hecho nosotros.
Si se trata de un pequeño proyecto de un sólo módulo (un war, un jar, etc...) y/o el ciclo de vida de la aplicación es muy reducido (es una pruebecilla nuestra, una pequeña aplicación de las que se hacen en casa en zapatillas, etc) no importa, claro. ¿Qué más da? La he hecho yo y podré volverla a construir con mi IDE favorito o con mi Ant dentro de un año cuando tenga que hacer un cambio. Incluso aunque cambie el IDE o cambie mi entorno, podré adaptarme a la situación sin más problemas, hacer las correcciones y volver a generar el empaquetado.

Ahora bien, si nos situamos ahora un escenario profesional, el tema cambia mucho. A continuación expondré los problemas que nos encontramos con esas formas de construir aplicaciones. Seguramente ya te habrás encontrado con ellos, y si no, es porque el proyecto no era lo suficientemente grande o, simplemente, es una cuestión de tiempo que te los encuentres.
  • Homogeneidad. Cada desarrollador tiene sus costumbres y sus ubicaciones (paths) para sus proyectos, librerías, ubicación del JDK, etc. Es difícil e incómodo homologar a todo un equipo de desarrollo en una única estructura de ficheros. Aunque Sun hiciese su propuesta de convenciones para proyectos (estructura y nombrado) hace mucho tiempo, casi ningún IDE lo respeta al 100%. Además, la heterogeneidad de los distintos Sistemas Operativos no hacen más que complicar la posibilidad de tener una estructura y ubicación homogénea para todo el mundo. Eso hace que los ficheros de proyecto (.nbproject, .project, etc) no puedan ser portados de unos desarrolladores a otros ni compartidos entre distintas máquinas. Esta estructura acaba teniendose que modificar manualmente en los distintos IDE's o en el fichero build.xml de ant. En el caso de los IDE's es particularmente grave, ya que la información de librerías, por ejemplo, descansa en la configuración local del IDE de cada desarrollador, que suele ser distinta para cada uno, con lo cual la construcción se torna algo tremendamente frágil y poco transparente.
  • Reproducibilidad. Necesitamos realizar tareas forma constante y estable nuestro proyecto: construccion, pruebas unitarias, informes, etc... Repetibles en el tiempo (hoy y dentro de un año) y en el espacio (en mi máquina de desarrollo, en integración, en preproducción...). Necesitamos fijar parámetros que no están implícitos en el proyecto en si y que acaban también fijados en los IDE's o en el script ant: versión de Java, versiones de librerías, destino de cada librería (sólo para compilar, sólo para desplegar con la aplicación, para compilar y desplegar...), ficheros de configuración, etc... Esto dificulta el mantenimiento y oculta información esencial del proyecto. Si el proyecto se sube a SVN y no lo volvemos a tocar en un año, a menudo nos encontramos con que las partes esenciales del proyecto han quedado ocultas en IDE's (o lo que es peor, se han perdido porque eran parte de la configuración local de un miembro del equipo) o permanecen en un script de ant poco amigable para modificar.
  • Gestión del cambio. Algo tan común como añadir una nueva librería al proyecto o realizar una actualización de una existente tiene demasiado impacto en el equipo hasta resultar ligeramente traumático: todos deben realizar las tareas de la descarga y localización de las librerías, la configuración de su IDE y de su proyecto y/o la adaptación de sus ficheros ant. Incluso un equipo de desarrollo con normas rígidas y paths homologados, además de sufrir esta falta de libertad, sigue estando expuesto a este tipo de problemas.
  • Gestión de dependencias (externas). Este es sin duda el aspecto más importante, por delicado, y por el impacto de sus consecuencias. Imagina el siguiente proyecto: un EAR compuesto por dos módulos WAR, tres módulos EJB y un par de módulos de de librerías comunes (jar). Uno de los desarrolladores añade al EAR una librería "A" que necesita uno de los módulos EJB y otro desarrollador añade otra librería "B" que necesita uno de los módulos JAR. Ambas librerías tienen sus propias dependencias: la librería "A" requiere de xxx-commons-2.3 y de asm-2.1, la librería "B" de yyy-commons (que a su vez depende de xxx-commons-1.5) y asm-3.0. Ya tenemos el problema servido. Como ya comenté en el artículo "Errores comunes de despliegue JEE", este tipo de problemas algunas veces sólo se presentan aleatoriamente, ya que el problema puede presentarse o no en función de la secuencia de carga del ClassLoader de la máquina de turno. Esto ocurre muchas más veces de lo que nos pueda parecer a simple vista, si bien en la mayoría de los casos los conflictos no plantean problemas porque muchas librerías mantienen una compatibilidad perfecta hacia atrás. En mi experiencia, es habitual que ocurra sin embargo con grandes frameworks tipo Hibernate, Spring, Struts, etc, con consecuencias muy desagradables. Sin Maven, la gestión de dependencias no la hace nadie, o lo que es lo mismo, se hace manualmente si el equipo de desarrollo es muy cuidadoso y está muy bien coordinado.
  • Gestión de dependencias (internas). Otro aspecto de los proyectos medianos con varios módulos interdependientes entre si es que, además de tener que realizar gestión de dependencias de librerías de terceros tenemos que gestionar nuestras propias dependencias. Por ejemplo, para el caso anterior, si ambos WAR necesitan de los proyectos JAR de librerías comunes, todos los desarrolladores de los WAR deberán tener también que tener los proyectos (código fuente incluído) de dichos JAR, para estar debidamente actualizados... O bien buscar otra forma de distribución manual de empaquetados que también exigirá un esfuerzo adicional de coordinación.

Como puedes suponer a estas alturas, Maven es una solución perfecta a todos los problemas comentados anteriormente (salvo para el último punto, para el que se requiere un colaborador, pero eso lo comentaré en la segunda parte). Maven es y sirve para muchas cosas (compilación, paso de pruebas unitarias, control de calidad, etc) pero, fundamentalmente, es la mejor herramienta de construcción posible. Hasta ahora, para una construcción lo más homogénea y reproducible posible necesitábamos unas normas (o convenciones) y ant. Pero ant es un lenguaje específico de dominio para la construcción de proyectos: te tienes que crear tus propios scripts basado en tus convenciones y el esfuerzo de mantenimiento es exponencial a la envergadura del proyecto. Maven ya te aporta ambas cosas: convenciones (sobre disposición de directorios de proyecto, por ejemplo) y todo el trabajo listo para usar sin tener que configurar nada. Con Maven puedes realmente bajarte unos fuentes y ejecutar un "mvn build" sobre el directorio que contiene el "pom.xml". Y tener en poco tiempo todos los empaquetados, un informe de construcción, pruebas unitarias realizadas, etc, etc.. con configuración cero.

No obstante, el punto fuerte (e incluso espectacular) de Maven es la gestión de dependencias: sólo por la gestión de dependencias transitivas que realiza de forma automática, ya merece la pena con creces. En este tema me recuerda a los repositorios de Ubuntu. Cuando quieres una librería, añades la dependencia y la versión que quieres de las disponibles y él se encargará de aprovisionarse de todas las dependencias transitivas adicionales.

Incluso aún respetando las convenciones de Maven (te las puedes saltar si especificas en el pom.xml cuáles son tus directorios) Maven te ofrece toda la libertad posible: permite que un equipo trabaje con IDE's heterogéneos: cada desarrollador con su IDE favorito. Lo único que debes subir a SVN son los fuentes y el pom.xml. Podrás construir el proyecto de forma repetible, independiente del IDE, ejecutar las pruebas unitarias y olvidarte de problemas de librerías.

Obviamente no te vas a olvidar de tu IDE o de ant. Toda esta maravilla de Maven tiene un precio: el rendimiento. Un build con Maven te lleva más segundos de los que estás dispuesto a considerar como aceptables para tu trabajo de desarrollo habitual. No es aceptable desarrollar realizando builds con Maven. Por lo menos para mi. Por eso yo continúo realizando los ciclos de iteración compilación-despliegue-pruebas con mi IDE. Maven lo dejo para realizar las construcciones, para subir a svn proyectos autónomos y autogenerables y para poder realizar las integraciones y las puestas a preproducción de una forma segura y repetible.


En esta primera parte he expuesto 2 de 3 de las herramientas más esenciales para el desarrollo en equipo de proyectos Java (especialmente JEE). En el siguiente artículo cerraré el círculo con la herramienta que falta: un gestor de repositorios de Maven. Y explicaré cómo, con tan sólo esas tres herramientas, tenemos un entorno de trabajo potente y seguro para equipos de tamaño mediano sin rígidas normativas ni procedimiento burocráticos.

Referencias:

(continuación: Parte II)

6 comentarios :

  1. Me ha gustado mucho tu introducción a SVN y a Maven.

    Por lo que veo en el día a día, el uso de un sistema de control de versiones es algo extendido. No lo es tanto el uso de Maven para la gestión de los proyectos. Ni siquiera lo es el uso de Ant para ello, aunque a día de hoy la alternativa más potente es Maven.

    Maven es una herramienta que he descubierto hace relativamente poco y que me encanta, por lo que la uso en mis proyectos personales. Me conquistó por la gestión de las dependencias, que, combinado con el uso de SVN, permite poner en marcha sin complicaciones un proyecto existente en cualquier equipo nuevo, aliviando la carga de trabajo que tenía que hacer hasta ahora en la configuración de las dependencias.

    También me gustaría mencionar otra de las principales características de Maven, que es el ciclo de vida del proyecto que define. Establece una serie de tareas que se ejecutan de forma secuencial, como la compilación, pruebas, empaquetamiento... Esto unifica la forma de trabajar en los proyectos y hasta me ha hecho poner más énfasis en las pruebas, ya que con Maven se ejecutan de forma automática al construir el proyecto.

    Espero tu próximo artículo sobre Nexus. Lo que conozco es otra alternativa, Apache Archiva, y supongo que ofrecerá funcionalidad similar.

    Un saludo.

    ResponderEliminar
  2. Agradezco mucho que compartas estas ideas...Nosotros usamos Maven en el proceso de construcción y va de cine. Además HUDSON como herramienta para automatizar procesos como creación de Informes de calidad estáticos (PMD, cheeckstyle, covertura...etc) como para desplegar en un entorno pre-producción las aplicaciones. Yo creo que Maven es una buena herramienta pero también es cierto que para proyectos reales, hay factores como el equipo de desarrollo y sus características, equipos, la red, IDE y licencias,...Que pueden a veces que sea más complicado usarlo que no usarlo, aunque yo creo que da y no quita nada...Además desacoplas el código de la configuración (es algo fundamental). Enhorabuena por tu explicación...Me he sentido representado (mi propia experiencia, ideas...) :)

    ResponderEliminar
  3. Hola, gracias por explicar, el problema es que tengo encargado implantar maven con artifactory o nexus...
    no consigo entender el funcionamiento completo.
    si me podeis ayudar : desi_22c@hotmail.com

    ResponderEliminar
  4. Cuál es tu pregunta? Qué es lo que no has entendido?

    ResponderEliminar
  5. Hemos publicado un artículo sobre
    Buenas prácticas de gestión de versiones con Subversion en:
    http://www.tecsisa.com/index.igw?item=1651

    ResponderEliminar
  6. Buen resumen. Gracias.
    Adicionalmente hay más recursos en español (manuales, presentaciones y documentación) en la wikipedia en español: http://es.wikipedia.org/wiki/Subversion#Enlaces_externos

    ResponderEliminar

Related Posts Plugin for WordPress, Blogger...
cookieassistant.com