¿Cómo le digo a Maven que use la última versión de una dependencia?

En Maven, las dependencias generalmente se configuran así:

 wonderful-inc dream-library 1.2.3  

Ahora, si está trabajando con bibliotecas que tienen lanzamientos frecuentes, actualizar constantemente la etiqueta puede ser algo molesto. ¿Hay alguna manera de decirle a Maven que use siempre la última versión disponible (del repository)?

NOTA:

¡Esta respuesta se aplica solo a Maven 2! Las metaversiones RELEASE RECIENTE y RELEASE mencionadas se han eliminado en Maven 3 “por el bien de comstackciones reproducibles” , hace más de 6 años. Consulte esta solución compatible con Maven 3 .


Si siempre quiere usar la versión más nueva, Maven tiene dos palabras clave que puede usar como alternativa a los rangos de versión. Debe usar estas opciones con cuidado ya que ya no tiene el control de los complementos / dependencias que está utilizando.

Cuando dependes de un complemento o una dependencia, puedes usar el valor de versión más reciente o LIBERACIÓN. LO MÁS RECIENTE se refiere a la última versión lanzada o instantánea de un artefacto particular, el artefacto desplegado más recientemente en un repository particular. RELEASE se refiere a la última versión no instantánea en el repository. En general, no es una buena práctica diseñar software que dependa de una versión no específica de un artefacto. Si está desarrollando software, es posible que desee utilizar LIBERACIÓN o ÚLTIMO como una conveniencia para que no tenga que actualizar los números de versión cuando se lanza una nueva versión de una biblioteca de terceros. Cuando libera el software, siempre debe asegurarse de que su proyecto dependa de versiones específicas para reducir las posibilidades de que su comstackción o su proyecto se vea afectado por una versión de software que no esté bajo su control. Use ÚLTIMA y RELEASE con precaución, si es que lo hace.

Vea la sección de syntax de POM del libro de Maven para más detalles. O vea este documento en los rangos de versión de dependencias , donde:

  • Un corchete ( [ & ] ) significa “cerrado” (inclusive).
  • Un paréntesis ( ( & ) ) significa “abierto” (exclusivo).

Aquí hay un ejemplo que ilustra las diversas opciones. En el repository de Maven, com.foo:my-foo tiene los siguientes metadatos:

  com.foo my-foo 2.0.0  1.1.1  1.0 1.0.1 1.1 1.1.1 2.0.0  20090722140000   

Si se requiere una dependencia de ese artefacto, tiene las siguientes opciones (por supuesto, se pueden especificar otros rangos de versión , solo se muestran los más relevantes aquí):

Declare una versión exacta (siempre se resolverá en 1.0.1):

 [1.0.1] 

Declare una versión explícita (siempre se resolverá en 1.0.1 a menos que ocurra una colisión, cuando Maven seleccione una versión coincidente):

 1.0.1 

Declare un rango de versión para todos los 1.x (se resolverá actualmente en 1.1.1):

 [1.0.0,2.0.0) 

Declare un rango de versión abierta (se resolverá a 2.0.0):

 [1.0.0,) 

Declare la versión como ÚLTIMA (se resolverá a 2.0.0) (eliminada de maven 3.x)

 LATEST 

Declare la versión como LIBERACIÓN (se resolverá a 1.1.1) (eliminada de maven 3.x):

 RELEASE 

Tenga en cuenta que, de manera predeterminada, sus propias implementaciones actualizarán la entrada “más reciente” en los metadatos de Maven, pero para actualizar la entrada de “liberación”, debe activar el “perfil de publicación” del Maven super POM . Puede hacer esto con “-Prelease-profile” o “-DperformRelease = true”


Vale la pena enfatizar que cualquier enfoque que permita a Maven elegir las versiones de dependencia (MÁS RECIENTE, LIBERACIÓN y rangos de versión) puede dejarlo abierto para generar problemas de tiempo, ya que las versiones posteriores pueden tener un comportamiento diferente (por ejemplo, el complemento de dependencia cambió previamente valor de verdadero a falso, con resultados confusos).

Por lo tanto, generalmente es una buena idea definir versiones exactas en los lanzamientos. Como señala la respuesta de Tim , maven-versions-plugin es una herramienta útil para actualizar versiones de dependencia, particularmente las versiones: use-latest-versions y versions: use-latest-releases goals.

Ahora sé que este tema es antiguo, pero leyendo la pregunta y la respuesta proporcionada por OP parece que el Plugin de Maven Versions podría haber sido una mejor respuesta a su pregunta:

En particular, los siguientes objectives podrían ser de utilidad:

  • versions: use-latest-versions busca en el pom todas las versiones que hayan sido una versión más nueva y las reemplaza con la última versión.
  • versions: use-latest-releases busca en el pom todas las versiones que no sean SNAPSHOT que hayan sido versiones más recientes y las reemplaza con la versión más reciente.
  • versions: update-properties actualiza las propiedades definidas en un proyecto para que correspondan a la última versión disponible de dependencias específicas. Esto puede ser útil si un conjunto de dependencias debe estar bloqueado en una versión.

Los siguientes otros objectives también se proporcionan:

  • versions: display-dependency-updates escanea las dependencias de un proyecto y produce un informe de aquellas dependencias que tienen versiones más nuevas disponibles.
  • versions: display-plugin-updates escanea los complementos de un proyecto y produce un informe de los complementos que tienen versiones más nuevas disponibles.
  • versions: update-parent actualiza la sección padre de un proyecto para que haga referencia a la versión más nueva disponible. Por ejemplo, si usa un POM raíz corporativo, este objective puede ser útil si necesita asegurarse de estar utilizando la última versión del POM raíz corporativo.
  • versions: update-child-modules actualiza la sección principal de los módulos secundarios de un proyecto para que la versión coincida con la versión del proyecto actual. Por ejemplo, si tiene un agregador pom que también es el padre de los proyectos que agrega y los hijos y las versiones principales no se sincronizan, este mojo puede ayudar a corregir las versiones de los módulos secundarios. (Tenga en cuenta que puede necesitar invocar a Maven con la opción -N para ejecutar este objective si su proyecto se rompe tan gravemente que no puede comstackr debido a la falta de correspondencia de la versión).
  • versions: lock-snapshots busca en el pom todas las versiones -SNAPSHOT y las reemplaza con la versión actual de ese sello -SNAPSHOT, por ejemplo -20090327.172306-4
  • versions: unlock-snapshots busca en el pom todas las instantáneas bloqueadas de timestamp y las reemplaza con -SNAPSHOT.
  • versions: resolve-ranges encuentra dependencias que usan rangos de versión y resuelve el rango a la versión específica que se usa.
  • versions: use-releases busca en el pom todas las versiones de -SNAPSHOT que se han publicado y las reemplaza con la versión de lanzamiento correspondiente.
  • versiones: use-next-releases busca en el pom todas las versiones que no sean SNAPSHOT que hayan sido más recientes y las reemplaza con la próxima versión.
  • versiones: use-next-versions busca en el pom todas las versiones que hayan sido una versión más nueva y las reemplaza con la próxima versión.
  • versions: commit elimina los archivos pom.xml.versionsBackup. Forma la mitad del “SCM de Poor Man” incorporado.
  • versions: revert restaura los archivos pom.xml de los archivos pom.xml.versionsBackup. Forma la mitad del “SCM de Poor Man” incorporado.

Solo pensé en incluirlo para futuras referencias.

Por favor, eche un vistazo a esta página (sección “Rangos de versiones de dependencia”). Lo que quizás quieras hacer es algo así como

 [1.2.3,) 

Estos rangos de versión se implementan en Maven2.

A diferencia de otros, creo que hay muchas razones por las que siempre querrás la última versión. Particularmente si está realizando una implementación continua (a veces tenemos 5 versiones en un día) y no desea hacer un proyecto de varios módulos.

Lo que hago es hacer que Hudson / Jenkins haga lo siguiente para cada comstackción:

 mvn clean versions:use-latest-versions scm:checkin deploy -Dmessage="update versions" -DperformRelease=true 

Es decir, uso el plugin de versiones y el plugin scm para actualizar las dependencias y luego verificarlo en el control de fuente. Sí, dejé que mi CI hiciera comprobaciones de SCM (que debes hacer de todos modos para el complemento de lanzamiento maven).

Deberá configurar el complemento de versiones para que solo actualice lo que desea:

   org.codehaus.mojo versions-maven-plugin 1.2  com.snaphop false true   

Utilizo el complemento de lanzamiento para hacer el lanzamiento que se ocupa de -SNAPSHOT y valida que hay una versión de lanzamiento de -SNAPSHOT (que es importante).

Si haces lo que hago, obtendrás la última versión para todas las comstackciones de instantáneas y la última versión de lanzamiento para comstackciones de versiones. Tus comstackciones también serán reproducibles.

Actualizar

Observé algunos comentarios que me preguntaron algunos detalles de este flujo de trabajo. Diré que ya no usamos este método y la gran razón por la cual el plugin de versiones de maven es defectuoso y, en general, es inherentemente defectuoso.

Es defectuoso porque para ejecutar el plugin de versiones para ajustar versiones, todas las versiones existentes deben existir para que el pom se ejecute correctamente. Ese es el plugin de versiones que no puede actualizarse a la última versión de nada si no puede encontrar la versión a la que se hace referencia en el pom. En realidad, esto es bastante molesto ya que a menudo limpiamos versiones antiguas por motivos de espacio en disco.

Realmente necesitas una herramienta separada de maven para ajustar las versiones (para que no dependas del archivo pom para ejecutarse correctamente). He escrito una herramienta de este tipo en el lenguaje humilde que es Bash. La secuencia de comandos actualizará las versiones como el complemento de la versión y verificará que el pom vuelva al control de la fuente. También se ejecuta como 100 veces más rápido que el complemento de versiones mvn. Desafortunadamente no está escrito de manera pública, pero si las personas están interesadas, podría hacerlo y ponerlo en una esencia o github.

Volviendo al flujo de trabajo, ya que se realizaron algunos comentarios acerca de que esto es lo que hacemos:

  1. Tenemos 20 o más proyectos en sus propios repositorys con sus propios trabajos jenkins
  2. Cuando lanzamos el complemento de lanzamiento Maven se utiliza. El flujo de trabajo de eso está cubierto en la documentación del complemento. El plugin de lanzamiento maven es una mierda (y estoy siendo amable) pero funciona. Algún día planeamos reemplazar este método con algo más óptimo.
  3. Cuando se libera uno de los proyectos, jenkins ejecuta un trabajo especial que llamaremos el trabajo de actualización de todas las versiones (cómo Jenkins sabe que su lanzamiento es complicado, en parte porque el complemento de lanzamiento de maven jenkins también es malo).
  4. La actualización de todas las versiones del trabajo sabe sobre los 20 proyectos. En realidad, es un agregador pom para ser específico con todos los proyectos en la sección de módulos en orden de dependencia. Jenkins ejecuta nuestro magic groovy / bash foo que hará que todos los proyectos actualicen las versiones a la última versión y luego se registren en los poms (de nuevo en orden de dependencia según la sección de módulos).
  5. Para cada proyecto si el pom ha cambiado (debido a un cambio de versión en alguna dependencia) se registra y luego hacemos ping a jenkins para que ejecute el trabajo correspondiente para ese proyecto (esto es para preservar el orden de dependencia de la comstackción, de lo contrario estarás a merced del progtwigdor de encuestas SCM).

En este punto, soy de la opinión de que es bueno tener el lanzamiento y la versión automática como una herramienta separada de tu construcción general de todos modos.

Ahora puede pensar que Maven es una mierda debido a los problemas enumerados anteriormente, pero esto en realidad sería bastante difícil con una herramienta de comstackción que no tiene una syntax explicable fácil de analizar extensible (también conocido como XML).

De hecho, agregamos atributos XML personalizados a través de los espacios de nombres para ayudar a guiar las secuencias de comandos de bash / groovy (por ejemplo, no actualizar esta versión).

La syntax de las dependencias se encuentra en la documentación de la especificación de requisitos de la versión de dependencias . Aquí está para completar:

El elemento de version dependencias define los requisitos de versión, que se utilizan para calcular la versión de dependencia efectiva. Los requisitos de versión tienen la siguiente syntax:

  • 1.0 : Requisito “suave” en 1.0 (solo una recomendación, si coincide con todos los demás rangos para la dependencia)
  • [1.0] : Requisito “difícil” en 1.0
  • (,1.0] : x <= 1.0
  • [1.2,1.3] : 1.2 <= x <= 1.3
  • [1.0,2.0) : 1.0 <= x <2.0
  • [1.5,) : x> = 1.5
  • (,1.0],[1.2,) : x <= 1.0 o x> = 1.2; varios conjuntos están separados por comas
  • (,1.1),(1.1,) : esto excluye 1.1 (por ejemplo, si se sabe que no funciona en combinación con esta biblioteca)

En su caso, podría hacer algo como [1.2.3,)

¿Posiblemente dependa de las versiones de desarrollo que obviamente cambian mucho durante el desarrollo?

En lugar de incrementar la versión de las versiones de desarrollo, puede usar una versión de instantánea que sobrescriba cuando sea necesario, lo que significa que no tendrá que cambiar la etiqueta de la versión en cada cambio menor. Algo así como 1.0-SNAPSHOT …

Pero tal vez estás tratando de lograr algo más;)

Quien esté usando ÚLTIMA VEZ, asegúrese de tener -U de lo contrario, no se extraerá la última instantánea.

 mvn -U dependency:copy -Dartifact=com.foo:my-foo:LATEST // pull the latest snapshot for my-foo from all repositories 

En el momento en que se planteó esta pregunta, hubo algunos problemas con los rangos de versión en maven, pero estos se han resuelto en las versiones más nuevas de maven. Este artículo capta muy bien cómo funcionan los rangos de versión y las mejores prácticas para comprender mejor cómo maven entiende las versiones: https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm#MAVEN8855

La verdad es que incluso en 3.x todavía funciona, sorprendentemente los proyectos se construyen y despliegan. Pero la palabra clave MÁS RECIENTE / LIBERACIÓN causa problemas en m2e y eclipse por todas partes, TAMBIÉN los proyectos dependen de la dependencia que se implementó a través de la ÚLTIMA / LIBERACIÓN no reconoce la versión.

También causará problemas si intenta definir la versión como propiedad, y lo referenciará en donde.

Entonces la conclusión es usar las versiones-maven-plugin si puedes.

A veces no quiere usar rangos de versión, porque parece que son “lentos” para resolver sus dependencias, especialmente cuando hay una entrega continua en el lugar y hay toneladas de versiones, principalmente durante el desarrollo intenso.

Una solución alternativa sería usar las versiones-maven-plugin . Por ejemplo, puede declarar una propiedad:

  1.1.1  

y agrega las versiones-maven-plugin a tu archivo pom:

    org.codehaus.mojo versions-maven-plugin 2.3    myname.version   group-id artifact-id latest         

Luego, para actualizar la dependencia, debe ejecutar los objectives:

 mvn versions:update-properties validate 

Si hay una versión más nueva que la 1.1.1, le dirá:

 [INFO] Updated ${myname.version} from 1.1.1 to 1.3.2 

Si quieres que Maven use la última versión de una dependencia, entonces puedes usar Versions Maven Plugin y cómo usar este plugin, Tim ya ha dado una buena respuesta, sigue su respuesta .

Pero como desarrollador, no recomendaré este tipo de prácticas. ¿POR QUÉ?

respuesta a por qué ya está dada por Pascal Thivent en el comentario de la pregunta

Realmente no recomiendo esta práctica (ni el uso de rangos de versión) por el bien de la reproducibilidad de comstackción. Una comstackción que comienza a fallar repentinamente por un motivo desconocido es mucho más molesto que actualizar manualmente un número de versión.

Recomendaré este tipo de práctica:

  3.1.2.RELEASE    org.springframework spring-core ${spring.version}   org.springframework spring-context ${spring.version}   

es fácil de mantener y fácil de depurar. Puedes actualizar tu POM en poco tiempo.