Utilice la última versión de una dependencia en Maven

1. Información general

Actualizar las dependencias de Maven manualmente siempre ha sido un trabajo tedioso, especialmente en proyectos con muchas bibliotecas que se publican con frecuencia.

En este tutorial, aprenderemos cómo explotar el complemento Versions Maven para mantener nuestras dependencias actualizadas .

Sobre todo, esto puede ser extremadamente útil cuando se implementan canalizaciones de Integración Continua que actualizan automáticamente las dependencias, prueban que todo aún funciona correctamente y confirman o deshacen el resultado, lo que sea apropiado.

2. Sintaxis del rango de versiones de Maven

En los días de Maven2, los desarrolladores podían especificar rangos de versiones dentro de los cuales los artefactos se habrían actualizado sin la necesidad de una intervención manual.

Esta sintaxis sigue siendo válida, se utiliza en varios proyectos y, por lo tanto, vale la pena conocerla:

No obstante, deberíamos evitarlo en favor del complemento Versions Maven cuando sea posible, porque el avance de versiones concretas desde el exterior nos da definitivamente más control que dejar que Maven maneje toda la operación por sí solo.

2.1. Sintaxis obsoleta

Maven2 también proporcionó dos valores de metaversión especiales para lograr el resultado: LATEST y RELEASE .

LATEST busca la versión más nueva posible, mientras que RELEASE apunta a la última versión que no sea SNAPSHOT.

De hecho, siguen siendo absolutamente válidos para la resolución regular de dependencias .

Sin embargo, este método de actualización heredado causaba imprevisibilidad donde CI necesitaba reproducibilidad. Por lo tanto, han quedado obsoletos para la resolución de dependencias de complementos.

3. Complemento Versions Maven

Versions Maven Plugin es la forma estándar de facto de manejar la administración de versiones hoy en día.

Desde comparaciones de alto nivel entre repositorios remotos hasta bloqueo de marcas de tiempo de bajo nivel para versiones SNAPSHOT, su lista masiva de objetivos nos permite cuidar cada aspecto de nuestros proyectos que involucran dependencias.

Si bien muchos de ellos están fuera del alcance de este tutorial, echemos un vistazo más de cerca a los que nos ayudarán en el proceso de actualización.

3.1. El caso de prueba

Antes de comenzar, definamos nuestro caso de prueba:

  • tres LANZAMIENTOS con una versión codificada
  • una LIBERACIÓN con una versión de propiedad, y
  • una instantánea
  commons-io commons-io 2.3   org.apache.commons commons-collections4 4.0   org.apache.commons commons-lang3 3.0   org.apache.commons commons-compress ${commons-compress-version}   commons-beanutils commons-beanutils 1.9.1-SNAPSHOT    1.15  

Finalmente, también excluiremos un artefacto del proceso al definir el complemento:

   org.codehaus.mojo versions-maven-plugin 2.7   org.apache.commons:commons-collections4      

4. Visualización de actualizaciones disponibles

En primer lugar, para saber simplemente si podemos actualizar nuestro proyecto y cómo, la herramienta adecuada para el trabajo son las versiones: display-dependency-updates :

mvn versions:display-dependency-updates

Como podemos ver, el proceso incluyó todas las versiones RELEASE. Incluso incluyó commons-collections4 ya que la exclusión en la configuración se refiere al proceso de actualización y no al de descubrimiento.

Por el contrario, ignoró el SNAPSHOT, por la razón de que es una versión de desarrollo que a menudo no es segura para actualizar automáticamente.

5. Actualización de las dependencias

Cuando se ejecuta una actualización por primera vez, el complemento crea una copia de seguridad del pom.xml denominada pom.xml.versionsBackup .

Si bien cada iteración alterará el pom.xml , el archivo de respaldo conservará el estado original del proyecto hasta el momento en que el usuario confirme (a través de las versiones mvn: commit ) o revertirá (a través de las versiones mvn: revert ) todo el proceso.

5.1. Conversión de INSTANTÁNEAS en LANZAMIENTOS

A veces sucede que un proyecto incluye un SNAPSHOT (una versión que todavía está en desarrollo).

Podemos utilizar versiones: use-releases para comprobar si se ha publicado el RELEASE correspondiente, y más aún para convertir nuestro SNAPSHOT en ese RELEASE al mismo tiempo:

mvn versions:use-releases 

5.2. Actualización a la próxima versión

Podemos migrar cada dependencia que no sea SNAPSHOT a su versión más cercana con versiones: use-next-releases :

mvn versions:use-next-releases 

Podemos ver claramente que el complemento actualizó commons-io , commons-lang3 e incluso commons-beanutils , que ya no es un SNAPSHOT, a su próxima versión.

Lo más importante es que ignoró c ommons-collections4 , que está excluido en la configuración del complemento, y commons-compress , que tiene un número de versión especificado dinámicamente a través de una propiedad.

5.3. Actualización a la última versión

La actualización de cada dependencia que no sea SNAPSHOT a su última versión funciona de la misma manera, simplemente cambiando el objetivo a las versiones: use-latest-releases :

mvn versions:use-latest-releases 

6. Filtering out Unwanted Versions

In case we want to ignore certain versions, the plugin configuration can be tuned to dynamically load rules from an external file:

 org.codehaus.mojo versions-maven-plugin 2.7  //www.mycompany.com/maven-version-rules.xml   

Most noteworthy, can also refer to a local file:

file:///home/andrea/maven-version-rules.xml 

6.1. Ignoring Versions Globally

We can configure our rules file so that it'll ignore versions matching a specific Regular Expression:

  .*-beta   

6.2. Ignoring Versions on a Per-Rule Basis

Finally, in case our needs are more specific, we can build a set of rules instead:

    .*-RELEASE 2.1.0     

7. Conclusion

We've seen how to check and update the dependencies of a project in a safe, automatic, and Maven3-compliant way.

As always, the source code is available over on GitHub, along with a script to help showcase everything step-by-step and without complexity.

Para verlo en acción, simplemente descargue el proyecto y ejecútelo en una terminal (o en Git Bash si usa Windows):

./run-the-demo.sh