2008-08-27 131 views
623

En Maven, dependencias generalmente se establecen así:¿Cómo le digo a Maven que use la última versión de una dependencia?

<dependency> 
    <groupId>wonderful-inc</groupId> 
    <artifactId>dream-library</artifactId> 
    <version>1.2.3</version> 
</dependency> 

Ahora, si se está trabajando con las bibliotecas que tienen frecuentes comunicados, la actualización constante de la versión < > etiqueta puede ser algo molesto. ¿Hay alguna manera de decirle a Maven que use siempre la última versión disponible (del repositorio)?

+134

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

+0

@Martin Conozco la convención xyz-SNAPSHOT, pero estaba pensando en las bibliotecas que se lanzan en las versiones finales al repositorio (es decir, yendo de dream-library-1.2.3.jar a dream-library-1.2.4. jar, y así sucesivamente). –

+8

@PascalThivent Actualizar manualmente un número de versión en un pom es un problema si está haciendo versiones continuas.Utilizo el plugin de versiones combinado con el plugin scm para superar esto (ver mi respuesta). –

Respuesta

618

NOTA:

Esta respuesta se aplica a Maven 2 solamente! Los LATEST y RELEASE menversions mencionados have been dropped in Maven 3 "for the sake of reproducible builds", hace más de 6 años. Por favor, consulte este Maven 3 compliant solution.


Si siempre quiere usar la última versión, 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 utilizar el valor de versión más reciente o LIBERAR. 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 repositorio particular. RELEASE se refiere a la última versión no instantánea en el repositorio. 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 compilació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.

Ver el POM Syntax section of the Maven book para más detalles. O ver este documento en Dependency Version Ranges, donde:

  • un corchete ([ & ]) significa "cerrado" (ambos inclusive).
  • Un paréntesis (( & )) significa "abierto" (exclusivo).

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

<?xml version="1.0" encoding="UTF-8"?><metadata> 
    <groupId>com.foo</groupId> 
    <artifactId>my-foo</artifactId> 
    <version>2.0.0</version> 
    <versioning> 
    <release>1.1.1</release> 
    <versions> 
     <version>1.0</version> 
     <version>1.0.1</version> 
     <version>1.1</version> 
     <version>1.1.1</version> 
     <version>2.0.0</version> 
    </versions> 
    <lastUpdated>20090722140000</lastUpdated> 
    </versioning> 
</metadata> 

Si se requiere una dependencia de ese artefacto, tiene las siguientes opciones (otros version ranges puede ser especificado por supuesto, sólo muestra la los relevantes aquí):

declarar una versión exacta (siempre a resolver 1.0.1):

<version>[1.0.1]</version> 

Declarar una versión explícita (siempre a resolver 1.0.1 a menos que ocurra una colisión, cuando Maven seleccione una versión correspondiente):

<version>1.0.1</version> 

Declara un intervalo de versiones 1.x para todos (en la actualidad se resolverá a 1.1.1):

<version>[1.0.0,2.0.0)</version> 

Declarar una gama versión abierta (resolverá a 2.0.0):

<version>[1.0.0,)</version> 

Declarar la versión como ACTUAL (resolverá a 2.0.0) (retirado de 3.x experto)

<version>LATEST</version> 

declarar la versión que LIBERACIÓN (resolverá a 1.1.1) (retirado de 3.x experto):

<version>RELEASE</version> 

Tenga en cuenta que por defecto sus propios despliegues actualizar la entrada "último" en los metadatos Maven, pero para actualizar la entrada de "liberación", debe activar el "perfil de publicación" del Maven super POM. Esto se puede hacer ya sea con "-Prelease perfil" o "-DperformRelease = true"


Vale la pena destacar que cualquier enfoque que permite Maven para recoger las versiones de dependencia (la última, la liberación y rangos de versión) puede lo deja abierto para generar problemas de tiempo, ya que las versiones posteriores pueden tener un comportamiento diferente (por ejemplo, el complemento de dependencia ha cambiado previamente un valor predeterminado de verdadero a falso, con resultados confusos).

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

+72

¡Hola rico! Parece que los marcadores de versión LIBERACIÓN y ÚLTIMA versión son [ya no son compatibles con Maven 3.x] (https://cwiki.apache.org/MAVEN/maven-3x-compatibility-notes.html#Maven3.xCompatibilityNotes-PluginMetaversionResolution). –

+13

Esa desaprobación parece aplicarse solo a los complementos en lugar de las dependencias normales si entiendo el documento correctamente –

+0

Creo que ÚLTIMA/LA LIBERACIÓN es muy importante para los complementos que proporcionan la funcionalidad de implementación. Por ejemplo, utilizamos un complemento que implementa una nueva versión de artefactos en nuestros servidores. Si los servidores cambian, lanzamos una nueva versión del complemento y todos los proyectos que usan este complemento deben actualizarse manualmente para usar la nueva versión del complemento deploy. – ATom

14

¿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 versión en cada cambio menor. Algo así como 1,0-INSTANTÁNEA ...

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

159

favor, eche un vistazo a this page (sección "Dependencia Versión Rangos"). Lo que es posible que desee hacer es algo como

<version>[1.2.3,)</version> 

Estos rangos de versión se implementan en Maven2.

+0

Por alguna razón esta opción no funcionó para mí, escogió una versión dentro del rango pero no la más nueva. – sorin

+3

Es posible que desee ver de cerca cómo Maven compara los números de versión; si no se ajusta a un patrón estricto, Maven lo compara como cadenas y no como números. –

+0

Esa página está en Codehaus y se describe a sí misma como "cosas que aún no se han implementado para Maven 2.0" ... La documentación de Maven en sí misma no dice nada acerca de los rangos de versión. ¿Me estoy perdiendo de algo? ¿Cuándo se introdujeron los rangos de versión? ¿Dónde se describen en la documentación oficial? – Shannon

290

Ahora sé que este tema es viejo, pero la lectura de la pregunta y la respuesta suministrada OP parece que el Maven Versions Plugin podría haber sido en realidad una mejor respuesta a su pregunta:

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

  • versiones: uso-latest-versiones busca en el POM para todas las versiones que han sido una versión más reciente y los reemplaza con la versión más reciente .
  • versiones: use-noticias de prensa busca en el pom para todos sin instantáneas versiones que han sido un nuevo liberación y los reemplaza con la versión más reciente liberación.
  • versiones: update-propiedades actualizaciones propiedades definidas en un proyecto de modo 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. También se proporcionan

Los siguientes objetivos:

  • versiones: visualización de dependencia actualizaciones exploraciones dependencias de un proyecto y produce un informe de esas dependencias que tienen nuevos versiones disponibles.
  • versiones: pantalla-plugin-actualizaciones escanea plugins de un proyecto y produce un informe de esos plugins que tienen versiones más recientes disponibles.
  • versiones: update-parent actualiza la sección principal de un proyecto tan que hace referencia a la versión más reciente disponible. Por ejemplo, si utiliza un POM raíz corporativo, este objetivo puede ser útil si necesita asegúrese de estar utilizando la última versión del POM raíz corporativo.
  • versiones: update-niños-módulos actualiza la sección de los padres de los niños módulos de un proyecto por lo que la versión coincide con la versión del proyecto actual . Por ejemplo, si usted tiene una pom agregador que es también el padre de los proyectos que agregados y los niños y versiones padres pierden la sincronización, esta mojo puede ayudar a solucionar las versiones de los módulos niño . (Tenga en cuenta que puede necesitar invocar Maven con la opción -N en para ejecutar este objetivo si su proyecto está roto tan gravemente que no se puede compilar debido a la versión error de coincidencia).
  • versiones: lock-instantáneas busca en el POM para todas las versiones -SNAPSHOT y los reemplaza con la versión fecha y hora actual de esa -SNAPSHOT, por ejemplo, -20090327.172306-4
  • versiones: Unlock-instantáneas busca en el POM para todas las versiones de marca de tiempo instantáneas cerradas y reemplaza con -SNAPSHOT.
  • versiones: resolve-ranges encuentra dependencias que utilizan rangos de versión y resuelve el rango a la versión específica que se utiliza.
  • versiones: Uso de prensa busca en el POM para todas las versiones -SNAPSHOT que han sido liberados y reemplaza con la versión correspondiente de liberación .
  • versiones: uso-junto-versiones busca en el POM para todas las versiones sin instantáneas que han sido un nuevo liberación y los sustituye por la siguiente versión liberación.
  • versiones: use-next-versions busca en el pom todas las versiones que han sido una versión más reciente y las reemplaza con la próxima versión.
  • versions: commit elimina los archivos pom.xml.versionsBackup. Formas la mitad del "Poor Man's SCM" incorporado.
  • versiones: revertir restaura los archivos pom.xml de los archivos pom.xml.versionsBackup. Formas la mitad del "Poor Man's SCM" incorporado.

Sólo pensé en incluirlo para futuras referencias.

+7

En este contexto, ¿cuál es la diferencia entre "versión" y "versión". –

+1

@BenNoland, creo que la diferencia en este caso es que la próxima versión puede no necesitar ser un artefacto de lanzamiento. P.ej. dado un artefacto versionado 1.0.0-SNAPSHOT, 1.0.0 y 1.0.1-SNAPSHOT, y una referencia pom a 1.0.0-SNAPSHOT, versiones: próximas versiones y versiones: las próximas versiones se resolverán a 1.0.0, mientras que las versiones: últimas versiones y versiones: las últimas versiones se resolverán con 1.0.1-SNAPSHOT y 1.0.0 respetuosamente. –

+1

Puede resolver algunas incertidumbres entre versiones/lanzamientos/instantáneas en esta bonita tabla aquí: http://goo.gl/iDq6PK – Ev0oD

70

A diferencia de otros, creo que hay muchas razones por las que puede querer siempre 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 Hudson/Jenkins hacer lo siguiente para cada proyecto de construcción:

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

Es decir que utilizo las versiones de plugins y el plugin SMC para actualizar las dependencias y luego comprobar que a control de código fuente. Sí, dejé que mi CI hiciera comprobaciones de SCM (que debes hacer de todos modos para el complemento de lanzamiento maven).

Usted desea instalar las versiones de plugins sólo para actualizar lo que quiere:

 <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>versions-maven-plugin</artifactId> 
      <version>1.2</version> 
      <configuration> 
       <includesList>com.snaphop</includesList> 
       <generateBackupPoms>false</generateBackupPoms> 
       <allowSnapshots>true</allowSnapshots> 
      </configuration> 
     </plugin> 

utilizo la versión plug-in para hacer el lanzamiento que se encarga de -SNAPSHOT y valida que hay una versión de lanzamiento de -SNAPSHOT (que es importante).

Si haces lo que hago obtendrá la versión más reciente para todos instantánea construye y la versión más reciente de las versiones de lanzamiento. Tus compilaciones también serán reproducibles.

actualización

me di cuenta de algunos comentarios que piden 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 erróneo porque a ejecutar las versiones de plugin para ajustar todas las versiones de las versiones existentes deben existir para el pom para funcionar 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 necesita una herramienta separada de maven para ajustar las versiones (para que no dependa 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 como algunos comentarios preguntaron acerca de que esto es lo que hacemos:

  1. Tenemos más o menos 20 proyectos en sus propios repositorios con sus propios puestos de trabajo Jenkins
  2. Cuando liberamos la liberación experto el complemento se usa 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 al 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 acerca de 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) está registrado e inmediatamente hacemos ping a jenkins para ejecutar el trabajo correspondiente para ese proyecto (esto es para preservar el orden de dependencia de la compilación; a merced del programador SCM Poll).

En este punto, soy de la opinión de que es bueno que la versión y la versión automática sean una herramienta separada de tu versión general.

Ahora usted podría pensar Maven especie de chupa debido a los problemas mencionados anteriormente, pero en realidad esto sería bastante difícil con una herramienta de construcción que no tiene una fácil declarativa para analizar sintaxis extensible (XML aka).

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

+4

Gracias por incluir una motivación (implementación continua) en su respuesta. –

+10

Creo que el punto importante aquí que las compilaciones son reproducibles con este método, mientras que, cuando se usan rangos de versión o -LATEST, ¡no lo son! –

5

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

+0

Si bien esto podría responder teóricamente a la pregunta, [sería preferible] (// meta.stackoverflow.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. –

3

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á un problema si intenta definir la versión como propiedad y lo referenciará en donde.

Así que la conclusión es usar el versions-maven-plugin si puede.

22

La sintaxis de dependencias se encuentra en la documentación Dependency Version Requirement Specification. Aquí está para completar:

Dependencias 'version elemento define los requisitos de versión, que se utilizan para calcular la versión de dependencia efectiva. requisitos de la versión tienen la siguiente sintaxis:

  • 1.0: "suave" requisito de 1.0 (sólo una recomendación, si coincide con todos los otros rangos de la dependencia)
  • [1.0]: requisito de "duro" 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 trabajo en combinación con esta biblioteca)

En su caso, usted podría hacer algo como <version>[1.2.3,)</version>

6

Quién está usando ÚLTIMA VEZ, por favor 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 
1

A veces no se desea utilizar rangos de versión, ya que parece que son "lentos" para resolver sus dependencias, especialmente cuando hay un suministro continuo en su lugar y hay un montón de versiones - principalmente durante pesada desarrollo.

Una solución alternativa sería utilizar el versions-maven-plugin. Por ejemplo, se puede declarar una propiedad:

<properties> 
    <myname.version>1.1.1</myname.version> 
</properties> 

y añadir la versiones-maven-plugin para su archivo POM:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>versions-maven-plugin</artifactId> 
      <version>2.3</version> 
      <configuration> 
       <properties> 
        <property> 
         <name>myname.version</name> 
         <dependencies> 
          <dependency> 
           <groupId>group-id</groupId> 
           <artifactId>artifact-id</artifactId> 
           <version>latest</version> 
          </dependency> 
         </dependencies> 
        </property> 
       </properties> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

Luego, con el fin de actualizar la dependencia, que tiene que ejecutar el objetivos:

mvn versions:update-properties validate 

Si existe una versión más reciente que la 1.1.1, que le dirá:

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