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

Java 在代码中从maven pom.xml检索版本,java,maven-2,version,Java,Maven 2,Version,在代码中从maven的pom.xml检索版本号的最简单方法是什么,即编程方式?假设您使用的是Java,您可以: 在(最常见的)您的src/main/resources目录中创建一个.properties文件(但在步骤4中,您可以告诉它去别处看看) 使用项目版本的标准Maven属性设置.properties文件中某些属性的值: foo.bar=${project.version} 在Java代码中,将属性文件中的值作为类路径中的资源加载(google提供了大量的示例,但是) 在Maven中

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

假设您使用的是Java,您可以:

  • 在(最常见的)您的
    src/main/resources
    目录中创建一个
    .properties
    文件(但在步骤4中,您可以告诉它去别处看看)

  • 使用项目版本的标准Maven属性设置
    .properties
    文件中某些属性的值:

    foo.bar=${project.version}
    
  • 在Java代码中,将属性文件中的值作为类路径中的资源加载(google提供了大量的示例,但是)

  • 在Maven中,启用资源筛选。这将导致Maven将该文件复制到输出类中,并在复制过程中转换资源,从而解释属性。您可以找到一些信息,但您通常只需在pom中找到这些信息:

    
    src/main/resources
    真的
    

  • 您还可以访问其他标准属性,如
    project.name
    project.description
    ,甚至可以访问pom中的任意属性
    ,等等。资源筛选与Maven配置文件相结合,可以在构建时为您提供可变的构建行为。当您在运行时使用
    -PmyProfile
    指定一个配置文件时,该配置文件可以启用随后可以显示在生成中的属性。

    打包的工件包含一个
    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
    
    许多应用程序在运行时使用此文件读取应用程序/jar版本,不需要进行任何设置


    上述方法的唯一问题是,该文件(当前)是在
    程序包
    阶段生成的,因此在测试等过程中不会出现(Jira有一个问题需要更改,请参阅)。如果这对您来说是一个问题,那么Alex描述的方法就是一条出路

    还有如下所述的方法:

    将其添加到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>
    

    我发现此方法更简单。

    使用此库可以轻松获得简单的解决方案。向清单中添加所需的内容,然后按字符串进行查询

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

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

    getClass().getPackage().getImplementationVersion()
    

    它在归档文件中读取生成的META-INF/MANIFEST.MF(设置为pom.xml的版本)的属性“Implementation Version”(实现版本)。

    补充@kieste发布的内容,我认为如果使用Spring boot,这是在代码中提供Maven构建信息的最佳方式:上的文档非常有用

    您只需激活执行器,并在
    应用程序中添加所需的属性。属性
    应用程序.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@
    

    接受的答案可能是将版本号静态地输入应用程序的最佳和最稳定的方法,但实际上并没有回答最初的问题:如何从pom.xml检索工件的版本号?因此,我想提供一个替代方案,说明如何在运行时动态地执行此操作:

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

    
    org.apache.maven
    maven模型
    3.3.9
    
    然后在Java中执行如下操作:

    package de.scrum\u master.app;
    导入org.apache.maven.model.model;
    导入org.apache.maven.model.io.xpp3.MavenXpp3Reader;
    导入org.codehaus.plexus.util.xml.pull.XmlPullParserException;
    导入java.io.FileReader;
    导入java.io.IOException;
    公共类应用程序{
    公共静态void main(字符串[]args)引发IOException,XmlPullParserException{
    MavenXpp3Reader reader=新的MavenXpp3Reader();
    Model=reader.read(新文件阅读器(“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
    我的神器
    1.0-快照
    

    更新2017-10-31:为了回答Simon Sobisch的后续问题,我修改了以下示例:

    @Value("${pom.version}")
    private String pomVersion;
    
    package de.scrum\u master.app;
    导入org.apache.maven.model.model;
    导入org.apache.maven.model.io.xpp3.MavenXpp3Reader;
    导入org.codehaus.plexus.util.xml.pull.XmlPullParserException;
    导入java.io.File;
    导入java.io.FileReader;
    导入java.io.IOException;
    导入java.io.InputStreamReader;
    公共类应用程序{
    公共静态void main(字符串[]args)引发IOException,XmlPullParserException{
    MavenXpp3Reader reader=新的MavenXpp3Reader();
    模型;
    如果((新文件(“pom.xml”)).exists())
    model=reader.read(新文件读取器(“pom.xml”);
    其他的
    model=reader.read(
    新的InputStreamReader(
    Application.class.getResourceAsStream(
    “/META-INF/maven/de.scrum-master.stackoverflow/aspectj-import-method/pom.xml”
    )
    )
    );
    System.out.println(model.getId());
    System.out.println(model.getGroupId());
    System.out.println(model.getArtifactId());
    System.out.println(model.getVersion());
    }
    }
    
    有时,当编写与项目版本相关的脚本时,Maven命令行就足够了,例如,通过URL从存储库检索工件:

    mvn help:evaluate -Dexpression=project.version -q -DforceStdout
    
    用法示例:

    VERSION=$(mvn帮助:evaluate-Dexpression=project.VERSION-q-DforceStdout)
    工件ID=$(mvn帮助:evaluate-Dexpression=project.artifactId-q-DforceStdout)
    组ID URL=$(mvn帮助:evaluate-Dexpression=project.groupId-q-DforceStdout | sed-e's#/#g')
    旋度-f-S-Ohttp://REPO-URL/mvn-repos/${GROUP\u ID\u URL}/${ARTIFACT\u ID}/${VERSION}/${ARTIFACT\u ID}-${VERSION}.jar
    
    参考:

    不幸的是,添加这一点会弄乱我的应用程序处理资源的方式
    <manifest>
        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
        <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
    </manifest>
    
    mvn help:evaluate -Dexpression=project.version -q -DforceStdout
    
    <build>
      <resources>
        <resource>
          <directory>src/main/resources</directory>
          <filtering>true</filtering>
        </resource>
      </resources>   
    </build>
    
    <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
    <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
    
    String version = getClass().getPackage().getImplementationVersion();
    
    # get values from pom.xml
    pom.version=@project.version@
    
    @Value("${pom.version}")
    private String pomVersion;
    
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <executions>
            <execution>
                <id>build-info</id>
                <goals>
                    <goal>build-info</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    
    @RestController
    @RequestMapping("/api")
    public class BuildInfoResource {
        @Autowired
        private BuildProperties buildProperties;
    
        
        @GetMapping("/build-info")
        public ResponseEntity<Map<String, Object>> getBuildInfo() {
            Map<String, String> buildInfo = new HashMap();
            buildInfo.put("appName", buildProperties.getName());
            buildInfo.put("appArtifactId", buildProperties.getArtifact());
            buildInfo.put("appVersion", buildProperties.getVersion());
            buildInfo.put("appBuildDateTime", buildProperties.getTime());
            return ResponseEntity.ok().body(buldInfo);
        }
    }