Maven: descargar dependencias antes de compilar

Hay algo en lo que es excelente maven: descargar dependencias, el problema reside en que no todas las dependencias están en algún repositorio de maven. En esta ocasión te enseñaré el escenario más complejo sobre como descargar dependencias y agregarlas a tu compilación usando únicamente maven.

¿Qué es Maven?

Maven es una herramienta de automatización enfocada en la integración continua que precede a la cultura devOps. Uno de sus propósitos clave siempre ha sido el estandarizar el manejo de versiones de dependencias y permitir realizar tareas de manera automatizada basándose en cierta configuración: el archivo pom.xml.

¿Si ya existen cosas muy modernas en CI/CD por qué usar maven?

Antes que anda es una herramienta que tiene décadas de experiencia, con todo el poder de Java, lenguaje en el que está programado y además representa un estándar muy difícil de superar en la comunidad de desarrollo. Adicional a esto existen algunas tareas o procesos que requieren que se maneje todo el ciclo de vida enteramente con Maven para garantizar que lo que se distribuye es totalmente portable y seguro.

¿Cuál es el caso más complejo que puede existir respecto a las dependencias?

El escenario más complejo que me he enfrentado es:

  1. Descargar un archivo comprimido desde una URL (da igual si es intranet o internet)
  2. Extraer el archivo en la carpeta de librerías
  3. Registrar todas esas librerías antes de que inicie el ciclo de vida del proyecto
  4. Compilar

Es importante hacer notar que dicho proyecto es un proyecto multimódulo, en donde cada módulo puede ser:

  1. Un wrapper OSGi para una librería existente en maven central
  2. Una librería común
  3. Una versión para una plataforma distinta, actualmente se soportan
    1. Aplicación multiplataforma Java (Java FX)
    2. Web
    3. Plugin de NetBeans
    4. Plugin de IDEA

Para ello abordaré cada problema en particular para demostrar como lo resolví.

Descargar un archivo comprimido con maven

Para ello me valí de el plugin llamado wagon-maven-plugin. Este recibe como parámetros:

  • La URL del archivo a descargar
  • El nombre del archivo descargado
  • El lugar donde se desea colocar la descarga
  • La opción de evitar la descarga si esta ya se había realizado con anterioridad

Esto en código se ve así:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>wagon-maven-plugin</artifactId>
    <version>2.0.2</version>
    <executions>
        <execution>
            <id>downloadIC</id>
            <phase>validate</phase>
            <goals><goal>download-single</goal></goals>
            <configuration>
                <url>https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/${idea.version}/</url>
                <fromFile>ideaIC-${idea.version}.zip</fromFile>
                <toFile>${project.basedir}/client-idea/lib/ideaIC-${idea.version}.zip</toFile>
                <skipIfExists>true</skipIfExists>
            </configuration>
        </execution>
    </executions>
</plugin>

Eso nos lleva a un pequeño problema, que es que cada plugin que se defina a nivel padre se ejecuta una vez por cada hijo, así que deberemos sobreescribir en todos los lugares que no queramos que se ejecute de la siguiente manera

<!-- disable IDEA downloading for this module -->
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>wagon-maven-plugin</artifactId>
    <version>2.0.2</version>
    <executions>
        <execution>
            <id>downloadIC</id>
            <phase/>
        </execution>
    </executions>
</plugin>

Extraer un archivo comprimido con maven

Como el paso anterior nos descarga nuestras dependencia ahora toca extraerla usando el plugin maven-antrun-plugin.

El plugin maven-antrun-plugin nos permite ejecutar tareas usando Ant. Ant es otro sistema anterior a maven muchísimo más configurable pero más complejo y menos estandarizado.

A este plugin le podemos especificar:

  • origen del archivo a descomprimir
  • destino donde se descomprimirá
  • si deseamos que sobreescriba archivos descomprimidos previamente

En código nos quedaría así:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>3.0.0</version>
    <executions>
        <execution>
            <id>prepare</id>
            <phase>validate</phase>
            <configuration>
                <target>
                    <echo message="unzipping file ${project.basedir}/client-idea/lib/ideaIC-${idea.version}.zip to ${project.basedir}/client-idea/lib" />
                    <unzip src="${project.basedir}/client-idea/lib/ideaIC-${idea.version}.zip" dest="${project.basedir}/client-idea/lib" overwrite="false" />
                </target>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

cabe mencionar que se ejecuta en la fase validate, es decir al terminar las tareas del padre y justo antes de empezar a ejecutar las tareas del hijo.

Cómo referencias dependencias en una carpeta con maven

Esta tarea ya es relativamente más fácil, se trata de registrar mediante el ámbito de sistema una dependencia, especificando la ubicación relativa de nuestro jar. Esto ya se peude realizar en los hijos de nuestro proyecto multimódulo en donde necesitemos las dependencias

El código se ve así:

<dependency>
    <groupId>com.jetbrains</groupId>
    <artifactId>util</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${idea.systemPath}/lib/util.jar</systemPath>
</dependency>

Despedida

De esta manera no solamente usamos maven para descargar dependencias, sino que nos encargamos de otras tareas de una manera que estamos seguros que funcionará en prácticamente todas las plataformas que soporten Java, y es allí donde todo este esfuerzo vale la pena. Es muy importante recalcar que para que este truco funcione se debe hacer el proyecto multimódulo y poner los plugins para descargar en el pom del padre.


  • Cursos de Código Facilito

    Te comparto aquí mis recomendaciones de cursos de Código Facilito. Codigofacilito.com es una plataforma virtual de cursos en idioma exclusivamente español que inició como un canal de YouTube. Opinión de la plataforma En mi opinión la plataforma aún es incipiente y los cursos necesitan más trabajo, ya que es muy común hallarse con clases de…


  • Cursos de LinkedIn Learning

    Te comparto aquí mis recomendaciones de cursos de Linkedin Learning. LinkedIn Learning es una plataforma virtual de cursos propiedad de Microsoft. Hallarás mucho material en inglés, pues prácticamente todos los cursos vienen con subtítulos en castellano y en la parte técnica son muy buenos debido a la adquisición de Lynda.com. En mi opinión la plataforma…


  • Mockito: Snippets de código

    Estos snippets de código para entrevista acerca de mockito espero te sean de mucha utilidad. Claro que también los puedes usar para tu desarrollo en el día a día. Mock básico Si te llegan a mostrar algo como esto es mejor que sospeches, mockito se usa principalmente para pruebas de integración. Si llegas a ver…


javapro.org