330 votes

Récupérer la version de maven pom.xml en code

Quelle est la manière la plus simple de récupérer le numéro de version du pom.xml de maven en code, c'est-à-dire de manière programmatique ?

333voto

Alex Miller Points 28225

En supposant que vous utilisez Java, vous pouvez

  1. Créez un fichier .properties dans (le plus souvent) votre répertoire src/main/resources (mais à l'étape 4, vous pouvez lui dire de chercher ailleurs).

  2. Définissez la valeur d'une propriété dans votre fichier .properties en utilisant la propriété Maven standard pour la version du projet : foo.bar=${project.version}.

  3. Dans votre code Java, chargez la valeur du fichier de propriétés en tant que ressource dans le classpath (vous trouverez de nombreux exemples de cette méthode sur Google).

  4. Dans Maven, activez le filtrage des ressources - cela amènera Maven à copier ce fichier dans vos classes de sortie et à traduire la ressource pendant cette copie, en interprétant la propriété. Vous pouvez trouver quelques informations ici mais la plupart du temps, vous faites ça dans votre pom :

    <build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
          <filtering>true</filtering>
        </resource>
      </resources>   
    </build>

Vous pouvez également accéder à d'autres propriétés standard comme project.name, project.description, ou même à des propriétés arbitraires que vous mettez dans votre pom, etc. Le filtrage des ressources, combiné aux profils Maven, permet de donner un comportement de construction variable au moment de la construction. Lorsque vous spécifiez un profil au moment de l'exécution avec -PmyProfile, vous pouvez activer des propriétés qui peuvent alors apparaître dans votre build.

2 votes

J'ai trouvé un code este qui ne modifie pas la configuration de Maven.

13 votes

Attention à ne pas utiliser le filtrage directement sur src/main/resources car cela peut traiter tous les fichiers situés dans ce répertoire, y compris les fichiers binaires. Pour éviter des comportements imprévisibles, il est préférable d'effectuer le filtrage sur un fichier src/main/resources-filtered répertoire, comme suggéré ici . En tout cas, merci pour cette belle astuce !

2 votes

La réponse ci-dessous, qui utilise le MavenXppReader pour obtenir le modèle réel, est vraiment utile, car elle n'a pas besoin d'exécuter quoi que ce soit pour trouver la valeur. Dans les cas où vous avez besoin de connaître la version avant d'exécuter quoi que ce soit, consultez les réponses ci-dessous ; il m'a été très utile de faire savoir à gradle quelle était la version d'un projet maven vérifié, afin de connaître à l'avance l'emplacement du jar de sortie.

132voto

kriegaex Points 6365

La réponse acceptée peut être la meilleure et la plus stable façon d'obtenir un numéro de version dans une application. statiquement mais ne répond pas réellement à la question originale : Comment récupérer le numéro de version de l'artefact à partir de pom.xml ? Ainsi, je veux offrir une alternative montrant comment le faire dynamiquement pendant l'exécution :

Vous pouvez utiliser Maven lui-même. Pour être plus exact, vous pouvez utiliser une bibliothèque Maven.

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-model</artifactId>
  <version>3.3.9</version>
</dependency>

Et ensuite faire quelque chose comme ça en Java :

package de.scrum_master.app;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.FileReader;
import java.io.IOException;

public class Application {
    public static void main(String[] args) throws IOException, XmlPullParserException {
        MavenXpp3Reader reader = new MavenXpp3Reader();
        Model model = reader.read(new FileReader("pom.xml"));
        System.out.println(model.getId());
        System.out.println(model.getGroupId());
        System.out.println(model.getArtifactId());
        System.out.println(model.getVersion());
    }
}

Le journal de la console est le suivant :

de.scrum-master.stackoverflow:my-artifact:jar:1.0-SNAPSHOT
de.scrum-master.stackoverflow
my-artifact
1.0-SNAPSHOT

Mise à jour 2017-10-31 : Afin de répondre à la question complémentaire de Simon Sobisch, j'ai modifié l'exemple comme suit :

package de.scrum_master.app;

import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Application {
  public static void main(String[] args) throws IOException, XmlPullParserException {
    MavenXpp3Reader reader = new MavenXpp3Reader();
    Model model;
    if ((new File("pom.xml")).exists())
      model = reader.read(new FileReader("pom.xml"));
    else
      model = reader.read(
        new InputStreamReader(
          Application.class.getResourceAsStream(
            "/META-INF/maven/de.scrum-master.stackoverflow/aspectj-introduce-method/pom.xml"
          )
        )
      );
    System.out.println(model.getId());
    System.out.println(model.getGroupId());
    System.out.println(model.getArtifactId());
    System.out.println(model.getVersion());
  }
}

2 votes

Cette méthode est presque identique à celle que j'utilise et fonctionne bien lorsqu'elle est lancée à partir d'eclipse, mais pas lorsqu'elle est lancée à partir de l'interface normale. package d jar (les classes de dépendance ne sont pas intégrées) et ne fonctionne pas lorsqu'il est empaqueté avec maven-assembly-plugin jar-with-dependencies Je reçois un java.io.FileNotFoundException: pom.xml (il est dans le bocal final comme META-INF/maven/my.package/myapp/pom.xml ). Avez-vous des conseils pour résoudre ce problème ?

1 votes

Ma solution est destinée à fonctionner de manière dynamique dans des environnements de développement, par exemple lorsqu'elle est utilisée dans des tests ou des outils lancés depuis un IDE ou une console. La réponse acceptée à cette question montre plusieurs façons d'empaqueter le numéro de version de manière statique dans vos artefacts. Je ne supposais pas du tout que pom.xml serait disponible dans les JARs. C'est bien que vous l'ayez là, cependant. Peut-être que vous pourriez simplement ajuster le chemin lors de l'ouverture du lecteur de fichiers et peut-être le rendre dépendant de la situation du classloader. Il faudrait que j'essaie par moi-même. N'hésitez pas à poser des questions complémentaires si cela ne vous aide pas.

2 votes

Bonjour @SimonSobisch, je viens de mettre à jour ma réponse afin de vous montrer comment faire ce que vous voulez. Mais soyez conscient du fait que je l'ai fait de manière rapide et sale, je n'aime pas particulièrement le code avec les constructeurs imbriqués.

80voto

Pascal Thivent Points 295221

Les artefacts emballés contiennent un META-INF/maven/${groupId}/${artifactId}/pom.properties dont le contenu ressemble :

#Generated by Maven
#Sun Feb 21 23:38:24 GMT 2010
version=2.5
groupId=commons-lang
artifactId=commons-lang

De nombreuses applications utilisent ce fichier pour lire la version de l'application/jar au moment de l'exécution, ce qui ne nécessite aucune configuration.

Le seul problème avec l'approche ci-dessus est que ce fichier est (actuellement) généré au cours de l'exécution de l package et ne sera donc pas présent lors des tests, etc. (il existe une question Jira pour changer cela, voir MJAR-76 ). Si c'est un problème pour vous, l'approche décrite par Alex est la meilleure.

12 votes

Pour les personnes cherchant un exemple de lecture des propriétés, ce post passe en revue plusieurs méthodes - javablog.fr/

59voto

adam.lofts Points 467

Il existe également la méthode décrite ici : http://www.christophkiehl.com/easy-way-to-display-your-apps-version-using-maven-and-manifest

Ajoutez ceci à pom.xml

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jar-plugin</artifactId>
      <configuration>
        <archive>
          <manifest>
            <mainClass>test.App</mainClass>
            <addDefaultImplementationEntries>
              true
            </addDefaultImplementationEntries>
          </manifest>
        </archive>
      </configuration>
    </plugin>
  </plugins>
</build>

Alors utilisez ceci :

App.class.getPackage().getImplementationVersion()

J'ai trouvé cette méthode plus simple.

18 votes

-1 - Cette solution n'a pas fonctionné pour moi ; la valeur de getImplementationVersion() était null . (maven version 3.0.4)

9 votes

Selon la phase... ne fonctionne que lorsque l'artefact est emballé, donc ne fonctionne pas sur les tests unitaires :-/

5 votes

Pour .war les artefacts, n'oubliez pas d'utiliser maven-war-plugin au lieu de maven-jar-plugin

27voto

electrobabe Points 571

Si vous utilisez un packaging mvn tel que jar ou war, utilisez :

getClass().getPackage().getImplementationVersion()

Il lit une propriété "Implementation-Version" du META-INF/MANIFEST.MF généré (qui est défini à la version du pom.xml) dans l'archive.

1 votes

Si vous cherchez comment inclure "Implementation-Version" dans MANIFEST.MF : stackoverflow.com/questions/921667/

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