在代码中从maven pom.xml中检索版本

mik*_*ail 236 java maven-2 version

在代码中从maven的pom.xml中检索版本号的最简单方法是什么,即以编程方式?

Ale*_*ler 245

假设你正在使用Java,你可以

  1. .properties在(最常见的)您的src/main/resources目录中创建一个文件(但在步骤4中,您可以告诉它在其他地方查找).

  2. .properties使用项目版本的标准Maven属性设置文件中某些属性的值: foo.bar=${project.version}

  3. 在您的Java代码中,从类路径中将属性文件中的值作为资源加载(谷歌有关如何执行此操作的大量示例,但这里是初学者的示例).

  4. 在Maven中,启用资源过滤 - 这将导致Maven将该文件复制到输出类中,并在该副本期间转换资源,从而解释属性.你可以在这里找到一些信息,但你大多只是在你的pom中这样做:

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

您还可以访问其他标准属性,例如project.name,project.description甚至是放在pom中的任意属性<properties>等.资源过滤与Maven配置文件结合使用,可以在构建时为您提供变量构建行为.在运行时指定配置文件时-PmyProfile,可以启用随后可以在构建中显示的属性.

  • 注意直接在`src/main/resources`上使用过滤,因为这可能会处理此目录中的所有文件,包括二进制文件.为了避免不可预测的行为,最好在`src/main/resources-filtered`目录上进行过滤,[如此处所示](https://maven.apache.org/plugins/maven-resources-plugin/examples/filter的.html).无论如何,谢谢你这个好戏! (7认同)
  • 从[这里](/sf/ask/2555071221/),如果您使用的是spring boot,则需要使用` @project.version@` 而不是 `${project.version}` (7认同)
  • 我发现了一个代码 [this](http://stackoverflow.com/questions/2712970/get-maven-artifact-version-at-runtime) 没有改变 Maven 配置。 (2认同)
  • 下面使用 MavenXppReader 获取实际模型的答案非常有用,因为它不需要运行任何东西来查找值。如果您需要在运行任何东西之前知道版本,请查看下面的答案;让 gradle 知道已检出的 maven 项目的版本对我很有帮助,因此我可以事先知道输出 jar 的位置。 (2认同)

kri*_*aex 80

接受的答案可能是将版本号静态地提供给应用程序的最佳和最稳定的方法,但实际上并未回答原始问题:如何从pom.xml中检索工件的版本号?因此,我想提供一个替代方案,展示如何在运行时动态地执行它:

你可以使用Maven本身.更确切地说,您可以使用Maven库.

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-model</artifactId>
  <version>3.3.9</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

然后在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());
    }
}
Run Code Online (Sandbox Code Playgroud)

控制台日志如下:

de.scrum-master.stackoverflow:my-artifact:jar:1.0-SNAPSHOT
de.scrum-master.stackoverflow
my-artifact
1.0-SNAPSHOT
Run Code Online (Sandbox Code Playgroud)

更新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());
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这与我使用的几乎相同,并且从 eclipse 启动时工作正常,但从正常的 `package`d jar 启动时则不然(依赖类未集成),并且在使用 maven- assembly 打包时不起作用 -插件 `jar-with-dependencies` 我得到一个 `java.io.FileNotFoundException: pom.xml` (它在最终的 jar 中为 `META-INF/maven/my.package/myapp/pom.xml`) - 任何提示如何解决这个问题? (2认同)
  • 嗨@SimonSobisch,我刚刚更新了我的答案,以告诉你如何做你想做的事.但是请注意我刚刚快速和脏的事实,我并不特别喜欢嵌套构造函数的代码. (2认同)

Pas*_*ent 72

打包的工件包含一个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
Run Code Online (Sandbox Code Playgroud)

许多应用程序使用此文件在运行时读取应用程序/ jar版本,所需的设置为零.

上述方法的唯一问题是该文件(当前)在package阶段期间生成,因此在测试期间不会出现等等(有一个Jira问题需要更改,请参阅MJAR-76).如果这对您来说是一个问题,那么Alex描述的方法就是您的选择.

  • 对于寻找阅读属性的例子的人来说,这篇文章介绍了几种方法 - http://www.javablog.fr/javaspring-get-and-display-the-version-from-manifest-mf.html (9认同)

小智 42

还有使用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>
Run Code Online (Sandbox Code Playgroud)

然后用这个:

App.class.getPackage().getImplementationVersion()
Run Code Online (Sandbox Code Playgroud)

我发现这种方法更简单.

  • -1 - 这个解决方案对我不起作用; `getImplementationVersion()`的值是`null`.(maven版本3.0.4) (17认同)
  • 取决于阶段...仅在工件被打包时有效,因此不适用于单元测试: - / (7认同)
  • 当你编译 jar 时它有效,否则无效 (3认同)
  • 对于`.war`工件,请记住使用`maven-war-plugin`而不是`maven-jar-plugin` (2认同)

coo*_*dje 17

为了补充@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@
Run Code Online (Sandbox Code Playgroud)


ele*_*abe 16

如果您使用mvn包装,如jar或war,请使用:

getClass().getPackage().getImplementationVersion()
Run Code Online (Sandbox Code Playgroud)

它读取归档中生成的META-INF/MANIFEST.MF(设置为pom.xml的版本)的属性"Implementation-Version".


t0r*_*r0X 7

有时,在编写与项目版本相关的脚本时,Maven 命令行就足够了,例如通过 URL 从存储库中检索工件:

mvn help:evaluate -Dexpression=project.version -q -DforceStdout
Run Code Online (Sandbox Code Playgroud)

用法示例:

mvn help:evaluate -Dexpression=project.version -q -DforceStdout
Run Code Online (Sandbox Code Playgroud)


Hor*_*use 7

使用 spring boot 时,此链接可能有用:https : //docs.spring.io/spring-boot/docs/2.3.x/reference/html/howto.html#howto-properties-and-configuration

使用 spring-boot-starter-parent,您只需将以下内容添加到您的应用程序配置文件中:

# get values from pom.xml
pom.version=@project.version@
Run Code Online (Sandbox Code Playgroud)

之后,该值可用,如下所示:

@Value("${pom.version}")
private String pomVersion;
Run Code Online (Sandbox Code Playgroud)


fed*_*der 6

使用此库可以轻松实现简单的解决方案.根据需要添加到清单中,然后按字符串查询.

 System.out.println("JAR was created by " + Manifests.read("Created-By"));
Run Code Online (Sandbox Code Playgroud)

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


ket*_*nkk 5

            <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>
Run Code Online (Sandbox Code Playgroud)

使用获取版本this.getClass().getPackage().getImplementationVersion()

PS别忘了添加:

<manifest>
    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
Run Code Online (Sandbox Code Playgroud)