コードでmaven pom.xmlからバージョンを取得する


256

コードで、つまりプログラムでmavenのpom.xmlからバージョン番号を取得する最も簡単な方法は何ですか?

回答:


263

Javaを使用している場合、次のことができます。

  1. .properties(最も一般的には)src/main/resourcesディレクトリにファイルを作成します(ただし、ステップ4で他の場所を探すように指示することができます)。

  2. .propertiesプロジェクトバージョンの標準のMavenプロパティを使用して、ファイル内のいくつかのプロパティの値を設定します。 foo.bar=${project.version}

  3. Javaコードで、クラスパスからリソースとしてプロパティファイルから値をロードします(これを行う方法の豊富な例についてはGoogleが、スターターの例を示します)。

  4. Mavenでリソースフィルタリングを有効にします。これにより、Mavenはそのファイルを出力クラスにコピーし、そのコピー中にリソースを変換して、プロパティを解釈します。あなたはここにいくつかの情報を見つけることができますが、ほとんどの場合あなたのポンでこれを行います:

    <ビルド>
      <資料>
        <リソース>
          <directory> src / main / resources </ directory>
          <filtering> true </ filtering>
        </リソース>
      </ resources>   
    </ビルド>

また、のような他の標準的な特性のために取得することができproject.nameproject.descriptionあなたはあなたのポンポンに入れたり、任意のプロパティ<properties>、Mavenのプロファイルと組み合わせるなど、リソースフィルタリングは、あなたのビルド時に変数のビルドの振る舞いを与えることができます。を使用して実行時にプロファイルを指定すると-PmyProfile、ビルドで表示されるプロパティを有効にできます。


2
私は、コードを発見した。このことは変更Mavenの設定。
Wendel

7
src/main/resourcesバイナリファイルを含め、このディレクトリにあるすべてのファイルを処理する可能性があるため、で直接フィルタリングを使用する場合は注意してください。予測できない動作を回避するにはsrc/main/resources-filteredここで提案されているように、ディレクトリでフィルタリングを行うことをお勧めします。とにかく、この素敵なトリックをありがとう!
SiZiOUS 2018

1
MavenXppReaderを使用して実際のモデルを取得する以下の答えは、値を見つけるために何も実行する必要がないため、非常に便利です。実行する前にバージョンを知る必要がある場合は、以下の答えを見てください。チェックアウトしたmavenプロジェクトのバージョンをgradleに知らせることは非常に役に立ち、出力jarの場所を事前に知ることができました。
Ajax

92

受け入れられた答えは、バージョン番号をアプリケーションに静的に取り込むための最良かつ最も安定した方法である可能性がありますが、実際には元の質問に答えません:pom.xmlからアーティファクトのバージョン番号を取得する方法?したがって、実行時に動的に行う方法を示す別の方法を提供したいと思います。

Maven自体を使用できます。より正確には、Mavenライブラリーを使用できます。

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

次に、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());
    }
}

コンソールログは次のとおりです。

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

2017-10-31の更新: Simon Sobischのフォローアップの質問に答えるために、この例を次のように変更しました。

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());
  }
}

1
これは私が使用しているものとほぼ同一であり、日食から起動時に罰金を動作しますが、通常のから始まっていないときpackageのmaven-組立・プラグインでパッケージ化するときDジャー(依存クラスが統合されていない)と動作しませんjar-with-dependenciesI GET a java.io.FileNotFoundException: pom.xml(それはとして最終的なjarにありますMETA-INF/maven/my.package/myapp/pom.xml)-これを解決する方法のヒントはありますか?
Simon Sobisch 2017年

1
私のソリューションは、開発環境で動的に機能することを意図しています。たとえば、IDEやコンソールから開始したテストやツールで使用する場合などです。この質問に対する承認された回答は、バージョン番号をアーティファクトに静的にパッケージ化するいくつかの方法を示しています。私はpom.xmlがJAR内で使用できるとはまったく想定していませんでした。あなたがそれをそこに持っていることはあなたにとって素晴らしいことです。ファイルリーダーを開くときにパスを調整し、クラスローダーの状況に応じてパスを調整することができます。私は自分で試さなければならないでしょう。これが役に立たない場合は、フォローアップの質問を自由に質問してください。
kriegaex 2017年

2
こんにちは@SimonSobisch、私はあなたが望むことをする方法を示すために私の答えを更新しました。しかし、私がそれをすばやく簡単に行ったという事実に注意してください。ネストされたコンストラクターを持つコードは特に好きではありません。
kriegaex 2017年

75

パッケージ化されたアーティファクトには、META-INF/maven/${groupId}/${artifactId}/pom.properties次のような内容のファイルが含まれています。

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

多くのアプリケーションがこのファイルを使用して、実行時にapplication / jarバージョンを読み取ります。セットアップは必要ありません。

上記のアプローチの唯一の問題は、このファイルが(現在)packageフェーズ中に生成され、テスト中に存在しないことです(これを変更するためのJiraの問題があります。MJAR-76を参照してください)。これがあなたにとって問題であるならば、アレックスによって説明されたアプローチは行くべき道です。


10
-プロパティを読み込む例を探している人々のために、この記事では、いくつかの方法を乗り越えjavablog.fr/...
chrismarx

43

Mavenを使用してアプリのバージョン番号を表示する簡単な方法で説明されている方法もあります

これを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>

次にこれを使用します:

App.class.getPackage().getImplementationVersion()

この方法の方が簡単であることがわかりました。


18
-1-この解決策は私にはうまくいきませんでした。の値はgetImplementationVersion()でしたnull。(mavenバージョン3.0.4)
Jesse Webb

7
フェーズに応じて...アーティファクトがパッケージ化されているときにのみ機能するため、単体テストでは機能しません:-/
wikier

2
以下のために.war成果物、使用することを忘れないmaven-war-plugin代わりにmaven-jar-plugin
cs_pupil

私にとって、これはTomcat 8では機能しますが、Tomcat 7では機能しません(getImplementationVersion()nullを返します)。
アルフォンソニシカワ

18

jarやwarなどのmvnパッケージを使用する場合は、以下を使用します。

getClass().getPackage().getImplementationVersion()

アーカイブ内の生成されたMETA-INF / MANIFEST.MF(pom.xmlのバージョンに設定されている)のプロパティ「Implementation-Version」を読み取ります。


18

@kiesteが投稿したものを補足するために、Spring-bootを使用している場合にコードでMavenビルド情報を使用できるようにする最良の方法だと思います。http://docs.spring.io/spring-boot/のドキュメントdocs / current / reference / htmlsingle /#production-ready-application-infoは非常に便利です。

あなただけのアクティブアクチュエータに必要とし、あなたが必要なプロパティを追加しますapplication.propertiesか、application.yml

Automatic property expansion using Maven

You can automatically expand info properties from the Maven project using resource filtering. If you use the spring-boot-starter-parent you can then refer to your Maven project properties via @..@ placeholders, e.g.

project.artifactId=myproject
project.name=Demo
project.version=X.X.X.X
project.description=Demo project for info endpoint
info.build.artifact=@project.artifactId@
info.build.name=@project.name@
info.build.description=@project.description@
info.build.version=@project.version@

6

このライブラリを使用すると、簡単なソリューションが簡単になります。必要なものをマニフェストに追加し、文字列でクエリします。

 System.out.println("JAR was created by " + Manifests.read("Created-By"));

http://manifests.jcabi.com/index.html


3

リポジトリからURLを介してアーティファクトを取得する場合など、プロジェクトバージョンに関連する何かをスクリプト化する場合、Mavenコマンドラインで十分な場合があります。

mvn help:evaluate -Dexpression=project.version -q -DforceStdout

使用例:

VERSION=$( mvn help:evaluate -Dexpression=project.version -q -DforceStdout )
ARTIFACT_ID=$( mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout )
GROUP_ID_URL=$( mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout | sed -e 's#\.#/#g' )
curl -f -S -O http://REPO-URL/mvn-repos/${GROUP_ID_URL}/${ARTIFACT_ID}/${VERSION}/${ARTIFACT_ID}-${VERSION}.jar

1
    <build>
            <finalName>${project.artifactId}-${project.version}</finalName>
            <pluginManagement>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-war-plugin</artifactId>
                        <version>3.2.2</version>
                        <configuration>
                            <failOnMissingWebXml>false</failOnMissingWebXml>
                            <archive>
                                <manifest>
                                    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                                    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                                </manifest>
                            </archive>
                        </configuration>
                    </plugin>
                 </plugins>
            </pluginManagement>
</build>

を使用してバージョンを取得 this.getClass().getPackage().getImplementationVersion()

PS追加することを忘れないでください:

<manifest>
    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>

0

ketankkの答えを参照して:

残念ながら、これを追加すると、アプリケーションがリソースをどのように処理したかがわかりません。

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

しかし、これをmaven-assemble-pluginの<manifest>タグ内で使用することでうまくいきました:

<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>

だから私は使用してバージョンを取得することができました

String version = getClass().getPackage().getImplementationVersion();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.