891 votes

Comment indiquer à Maven d'utiliser la dernière version d'une dépendance ?

Dans Maven, les dépendances sont généralement configurées de la manière suivante :

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

Maintenant, si vous travaillez avec des bibliothèques qui ont des versions fréquentes, la mise à jour constante de la balise <version> peut être quelque peu ennuyeuse. Existe-t-il un moyen de dire à Maven de toujours utiliser la dernière version disponible (du dépôt) ?

0 votes

@Martin Je suis conscient de la convention x.y.z-SNAPSHOT, mais je pensais aux bibliothèques qui sont publiées dans des versions finales dans le référentiel (c'est-à-dire passer de dream-library-1.2.3.jar à dream-library-1.2.4.jar, et ainsi de suite).

220 votes

Je ne recommande vraiment pas cette pratique (ni l'utilisation de plages de versions) pour le bien de la reproductibilité de la compilation. Une compilation qui échoue soudainement pour une raison inconnue est bien plus ennuyeuse que la mise à jour manuelle d'un numéro de version.

17 votes

@PascalThivent La mise à jour manuelle d'un numéro de version dans un pom est pénible si vous faites des versions continues. J'utilise le plugin versions combiné avec le plugin scm pour contourner ce problème (voir ma réponse).

834voto

Rich Seller Points 46052

NOTE :

Le mentionné LATEST y RELEASE métaversions ont été abandonnés pour les dépendances des plugins dans Maven 3 "pour des raisons de reproductibilité des constructions". il y a plus de 6 ans. (Ils fonctionnent toujours parfaitement bien pour les dépendances ordinaires). Pour les dépendances des plugins, veuillez vous référer à ceci Solution conforme à Maven 3 .


Si vous voulez toujours utiliser la version la plus récente, Maven dispose de deux mots-clés que vous pouvez utiliser comme alternative aux plages de versions. Vous devez utiliser ces options avec précaution car vous n'avez plus le contrôle des plugins/dépendances que vous utilisez.

Lorsque vous dépendez d'un plugin ou d'une dépendance, vous pouvez utiliser la valeur de version LATEST ou RELEASE. LATEST fait référence à la dernière version publiée ou snapshot d'un artefact particulier, l'artefact le plus récemment déployé dans un référentiel particulier. RELEASE fait référence à la dernière version non snapshot du référentiel. En général, ce n'est pas une bonne pratique de concevoir un logiciel qui dépend d'une version non spécifique d'un artefact. Si vous développez un logiciel, vous pouvez utiliser RELEASE ou LATEST par commodité afin de ne pas avoir à mettre à jour les numéros de version lorsqu'une nouvelle version d'une bibliothèque tierce est publiée. Lorsque vous diffusez un logiciel, vous devez toujours vous assurer que votre projet dépend de versions spécifiques afin de réduire les risques que votre compilation ou votre projet soit affecté par une version du logiciel qui n'est pas sous votre contrôle. Utilisez LATEST et RELEASE avec prudence, voire pas du tout.

Voir le Section Syntaxe POM du livre Maven pour plus de détails. Ou voyez ce document sur Gammes de versions de dépendances où :

  • Un crochet ( [ & ] ) signifie "fermé" (inclusivement).
  • Une parenthèse ( ( & ) ) signifie "ouvert" (exclusif).

Voici un exemple illustrant les différentes options. Dans le référentiel Maven, com.foo:my-foo a les métadonnées suivantes :

<?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 une dépendance sur cet artefact est requise, vous avez les options suivantes (autres gammes de versions peuvent être spécifiés bien sûr, nous ne montrons ici que ceux qui sont pertinents) :

Déclarer une version exacte (sera toujours résolu à 1.0.1) :

<version>[1.0.1]</version>

Déclarer une version explicite (qui sera toujours résolue par la version 1.0.1, sauf en cas de collision, auquel cas Maven sélectionnera une version correspondante) :

<version>1.0.1</version>

Déclarer une gamme de versions pour toutes les 1.x (sera actuellement résolu à 1.1.1) :

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

Déclarer une gamme de versions non limitée (sera résolu à 2.0.0) :

<version>[1.0.0,)</version>

Déclare la version comme LATEST (sera résolu à 2.0.0) (supprimé de maven 3.x)

<version>LATEST</version>

Déclare la version comme RELEASE (sera résolue en 1.1.1) (supprimé de maven 3.x) :

<version>RELEASE</version>

Notez que, par défaut, vos propres déploiements mettront à jour l'entrée "latest" dans les métadonnées Maven, mais que pour mettre à jour l'entrée "release", vous devez activer le "release-profile" à partir de l'onglet "release". Maven super POM . Vous pouvez le faire avec "-Prelease-profile" ou "-DperformRelease=true".


Il est important de souligner que toute approche qui permet à Maven de choisir les versions des dépendances (LATEST, RELEASE et plages de versions) peut vous exposer à des problèmes de temps de construction, car les versions ultérieures peuvent avoir un comportement différent (par exemple, le plugin de dépendance a déjà changé une valeur par défaut de true à false, avec des résultats déroutants).

Il est donc généralement judicieux de définir des versions exactes dans les versions. Comme La réponse de Tim souligne que le maven-versions-plugin est un outil pratique pour la mise à jour des versions des dépendances, en particulier la version versions:use-latest-versions y versions:use-latest-releases objectifs.

2 votes

Je pense que LATEST/RELEASE est très important pour les plugins qui fournissent une fonctionnalité de déploiement. Par exemple, nous utilisons un plugin qui déploie une nouvelle version des artefacts sur nos serveurs. Si les serveurs changent, nous publions une nouvelle version du plugin et tous les projets qui utilisent ce plugin doivent être mis à jour manuellement pour utiliser la nouvelle version du plugin de déploiement.

9 votes

@RichSeller hey Rich ; J'ai passé un peu de temps sur ce sujet avant de me rendre compte que ce n'est plus disponible dans Maven 3.0 ;) Pourrais-tu modifier la réponse pour qu'elle commence par une mise à jour indiquant la dépreaction de Maven 3.0 ? Merci beaucoup !

6 votes

Je pense qu'un bon équilibre serait de verrouiller la version majeure mais d'obtenir la dernière version mineure (ou patch) (celle qui est utilisée pour les corrections de bogues uniquement dans l'artefact dont vous dépendez). Avec la syntaxe actuelle, cela semble n'être possible qu'avec une plage comme (note : commence par des crochets et se termine par des parenthèses) : [1.1,2.0)

422voto

Tim Points 8971

Maintenant, je sais que ce sujet est vieux, mais en lisant la question et la réponse fournie par le PO, il semble que la Plugin Versions Maven aurait pu être une meilleure réponse à sa question :

En particulier, les objectifs suivants pourraient être utiles :

  • versions:use-latest-versions recherche le pom pour toutes les versions qui ont été une version plus récente et les remplace par la dernière version.
  • versions:use-latest-releases recherche dans le pom tous les éléments non-SNAPSHOT qui ont été une version plus récente version et les remplace par la dernière version.
  • versions:update-properties met à jour les propriétés définies dans un pour qu'elles correspondent à des la dernière version disponible de dépendances spécifiques. Cela peut être utile si une suite de dépendances doivent toutes être verrouillées à une seule version.

Les autres objectifs suivants sont également prévus :

  • versions:afficher les mises à jour des dépendances analyse les dépendances d'un projet et produit un rapport sur les dépendances qui ont de nouvelles disponibles.
  • versions:afficher les mises à jour des plugins analyse les plugins d'un projet et produit un rapport sur les plugins qui ont des versions plus récentes disponibles.
  • versions:update-parent met à jour la section parent d'un projet de sorte que afin qu'elle fasse référence à la plus récente version disponible. Par exemple, si vous utilisez un POM racine d'entreprise, cet objectif objectif peut être utile si vous devez vous assurer que vous utilisez la dernière version du POM racine de l'entreprise.
  • versions:update-modules-enfants met à jour la section parent de la modules enfants d'un projet afin que la version corresponde à la version du projet actuel. Par exemple, si vous avez un agrégateur pom qui est aussi le parent pour les projets qu'il qu'il agrège et que les versions enfant et parents ne sont pas synchronisées, ce mojo peut aider à corriger les versions des modules enfants. (Remarque : vous devrez peut-être invoquer Maven avec l'option -N pour pouvoir afin d'exécuter ce but si votre projet est tellement cassé qu'il ne peut ne peut pas être construit à cause de la version ne correspond pas).
  • versions:lock-snapshots recherche le pom pour tous les -SNAPSHOT et les remplace par la version version de l'horodatage actuel de ce -SNAPSHOT, par exemple -20090327.172306-4
  • versions:déverrouiller les instantanés recherche dans le pom tous les timestamp et les remplace par des versions les remplace par -SNAPSHOT.
  • versions:résoudre les gammes trouve les dépendances en utilisant les plages de versions et résout la plage à la version spécifique spécifique utilisée.
  • versions:use-releases recherche dans le pom toutes les versions -SNAPSHOT qui ont été publiées et les remplace avec la version correspondante de la version correspondante.
  • versions:utiliser les prochaines versions recherche dans le pom tous les éléments non-SNAPSHOT qui ont été une version plus récente et les remplace par la version prochaine version.
  • versions:use-next-versions recherche le pom pour toutes les versions qui ont été une version plus récente et les remplace par la version suivante.
  • versions:commit supprime les fichiers pom.xml.versionsBackup. Formulaires la moitié de la solution intégrée "Poor Man's SCM" INTÉGRÉ.
  • versions:revert restaure les fichiers pom.xml du fichier pom.xml.versionsBackup. Formulaires la moitié de la solution intégrée "Poor Man's SCM" INTÉGRÉ.

J'ai juste pensé que je devais l'inclure pour toute référence future.

10 votes

Dans ce contexte, quelle est la différence entre "release" et "version" ?

2 votes

@BenNoland, je crois que la différence dans ce cas est que la prochaine version n'aura peut-être pas besoin d'être un artefact de version. Par exemple, étant donné un artefact versionné 1.0.0-SNAPSHOT, 1.0.0, et 1.0.1-SNAPSHOT, et une référence pom à 1.0.0-SNAPSHOT, versions:next-versions et versions:next-releases résoudront à 1.0.0, alors que versions:latest-versions et versions:latest-releases résoudront à 1.0.1-SNAPSHOT et 1.0.0 respectivement.

3 votes

Imprimer tous les objectifs possibles et non liés n'est pas utile.

175voto

Martin Klinke Points 4157

Veuillez jeter un coup d'œil à cette page (section "Plages de versions des dépendances"). Ce que vous pourriez vouloir faire est quelque chose comme

<version>[1.2.3,)</version>

Ces plages de versions sont mises en œuvre dans Maven2.

4 votes

Vous voudrez peut-être examiner de plus près la façon dont Maven compare les numéros de version - si vous ne vous conformez pas à un modèle strict, Maven les compare sous forme de chaînes de caractères et non de chiffres.

0 votes

Cette page est sur Codehaus, et se décrit comme des choses "qui n'ont pas encore été implémentées pour Maven 2.0"... La documentation Maven elle-même ne dit rien sur les gammes de versions. Est-ce que quelque chose m'échappe ? Quand les plages de versions ont-elles été introduites ? Où sont-elles décrites dans la documentation officielle ?

4 votes

Vous avez tort, la gamme de versions signifie que toutes les versions sont OK à partir de la 1.2.3. Ce n'est pas du tout la dernière version.

91voto

Adam Gent Points 15055

Contrairement à d'autres, je pense qu'il y a de nombreuses raisons pour lesquelles vous pourriez veulent toujours le dernier cri version. En particulier si vous faites du déploiement continu (nous avons parfois 5 versions par jour) et que vous ne voulez pas faire un projet multi-module.

Ce que je fais, c'est que Hudson/Jenkins fait ce qui suit pour chaque construction :

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

C'est-à-dire que j'utilise le plugin versions et le plugin scm pour mettre à jour les dépendances et ensuite les enregistrer dans le contrôle de source. Oui, je laisse mon CI faire les vérifications SCM (ce que vous devez faire de toute façon pour le plugin maven release).

Vous devez configurer le plugin de versions pour qu'il ne mette à jour que ce que vous voulez :

<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>

J'utilise le plugin release pour faire le release qui s'occupe de -SNAPSHOT et valide qu'il y a une version release de -SNAPSHOT (ce qui est important).

Si vous faites comme moi, vous obtiendrez la dernière version pour tous les snapshot builds et la dernière version pour les release builds. Vos constructions seront également reproductibles.

Mise à jour

J'ai remarqué que certains commentaires demandaient des précisions sur ce flux de travail. Je dirai que nous n'utilisons plus cette méthode et que la raison principale en est que le plugin des versions maven est bogué et, en général, est intrinsèquement défectueux.

Il est défectueux parce que pour exécuter le plugin de versions pour ajuster les versions, toutes les versions existantes doivent exister pour que le pom fonctionne correctement. C'est-à-dire que le plugin versions ne peut pas mettre à jour la dernière version de quoi que ce soit s'il ne peut pas trouver la version référencée dans le pom. C'est en fait assez ennuyeux car nous nettoyons souvent les anciennes versions pour des raisons d'espace disque.

Vous avez vraiment besoin d'un outil distinct de maven pour ajuster les versions (afin de ne pas dépendre du fichier pom pour fonctionner correctement). J'ai écrit un tel outil dans le langage simple qu'est Bash. Le script mettra à jour les versions comme le plugin de version et remettra le pom dans le contrôle de source. Il fonctionne également 100 fois plus vite que le plugin mvn versions. Malheureusement, il n'est pas écrit de manière à être utilisé publiquement, mais si les gens sont intéressés, je pourrais le faire et le mettre dans un gist ou un github.

Pour en revenir au flux de travail, comme l'ont demandé certains commentaires, c'est ce que nous faisons :

  1. Nous avons une vingtaine de projets dans leurs propres dépôts avec leurs propres tâches Jenkins.
  2. Lorsque nous publions, le plugin maven release est utilisé. Le flux de travail est couvert par la documentation du plugin. Le plugin maven release est un peu nul (et je suis gentil) mais il fonctionne. Un jour, nous prévoyons de remplacer cette méthode par quelque chose de plus optimal.
  3. Lorsque l'un des projets est publié, Jenkins exécute alors un travail spécial que nous appellerons le travail de mise à jour de toutes les versions (comment Jenkins sait qu'il s'agit d'une version est une manière compliquée, en partie parce que le plugin maven jenkins release est assez merdique aussi).
  4. La tâche de mise à jour de toutes les versions connaît les 20 projets. Il s'agit en fait d'un pom agrégateur pour être précis avec tous les projets de la section modules dans l'ordre des dépendances. Jenkins exécute notre groovy/bash foo magique qui va extraire tous les projets, mettre à jour les versions à la dernière et ensuite vérifier les poms (encore une fois dans l'ordre de dépendance basé sur la section des modules).
  5. Pour chaque projet, si le pom a changé (en raison d'un changement de version d'une dépendance), il est vérifié et nous envoyons immédiatement un ping à jenkins pour exécuter le travail correspondant à ce projet (ceci afin de préserver l'ordre des dépendances de construction, sinon vous êtes à la merci du planificateur de sondage SCM).

À ce stade, je pense que c'est une bonne chose d'avoir la version de lancement et la version automatique comme un outil distinct de votre construction générale de toute façon.

Maintenant, vous pouvez penser que maven est nul à cause des problèmes énumérés ci-dessus, mais cela serait en fait assez difficile avec un outil de construction qui ne dispose pas d'une déclaration facile à analyser. extensible syntaxe (alias XML).

En fait, nous ajoutons des attributs XML personnalisés par le biais d'espaces de noms pour aider à donner des indices à bash/groovy scripts (par exemple, ne pas mettre à jour cette version).

5 votes

Merci d'avoir inclus une motivation (le déploiement continu) dans votre réponse.

13 votes

Je pense que le point important ici est que les constructions sont reproductibles avec cette méthode, alors que, en utilisant les plages de versions ou -LATEST, elles ne le sont pas !

0 votes

Je voudrais détacher la solution en utilisant un outil externe qui modifie le projet pom avant de lancer la construction. Nous utilisons également cette approche car version-range-plugin est intrinsèquement buggué par exemple en prenant en compte les dates et pas seulement les versions.

16voto

Martin Klinke Points 4157

Vous dépendez peut-être de versions de développement qui, de toute évidence, changent beaucoup au cours du développement ?

Au lieu d'incrémenter la version des versions de développement, vous pourriez simplement utiliser une version instantanée que vous écraseriez si nécessaire, ce qui signifie que vous n'auriez pas à changer la balise de version à chaque changement mineur. Quelque chose comme 1.0-SNAPSHOT...

Mais peut-être essayez-vous d'atteindre quelque chose d'autre ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X