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


当前回答

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

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

其他回答

使用这个库可以获得简单的解决方案。向清单中添加您需要的任何内容,然后按字符串查询。

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

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

第一步:如果你使用Spring Boot,你的pom.xml应该已经包含了Spring - Boot -maven-plugin。您只需要添加以下配置。

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

它指示插件执行build-info目标,默认情况下不会运行。这会生成关于应用程序的构建元数据,包括工件版本、构建时间等。

步骤2:使用buildProperties bean访问构建属性。在我们的例子中,我们创建了一个restResource来访问我们的webapp中的构建信息

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

我希望这能有所帮助

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

我在白天的工作中也遇到了同样的问题。尽管许多答案将有助于找到特定工件的版本,但我们需要获得不是应用程序直接依赖的模块/jar的版本。类路径在应用程序启动时由多个模块组装而成,主应用程序模块不知道后来添加了多少jar。

这就是为什么我提出了一个不同的解决方案,它可能比必须从jar文件中读取XML或属性更优雅一些。

这个想法

使用Java服务加载器方法可以在以后添加尽可能多的组件/构件,这些组件/构件可以在运行时提供它们自己的版本。创建一个非常轻量级的库,只需几行代码来读取、查找、筛选和排序类路径上的所有工件版本。 创建一个maven源代码生成器插件,在编译时为每个模块生成服务实现,在每个jar中打包一个非常简单的服务。

解决方案

解决方案的第一部分是构件版本服务库,现在可以在github和MavenCentral上找到它。它涵盖了服务定义和在运行时获得工件版本的几种方法。

第二部分是artifact-version-maven-plugin,也可以在github和MavenCentral上找到。它用于为每个工件提供一个轻松的生成器来实现服务定义。

例子

获取所有带有坐标的模块

不再读取jar清单,只是一个简单的方法调用:

// iterate list of artifact dependencies
for (Artifact artifact : ArtifactVersionCollector.collectArtifacts()) {
    // print simple artifact string example
    System.out.println("artifact = " + artifact);
}

返回一组已排序的工件。要修改排序顺序,提供一个自定义比较器:

new ArtifactVersionCollector(Comparator.comparing(Artifact::getVersion)).collect();

这样,工件列表将按版本号排序返回。

找到一个特定的工件

ArtifactVersionCollector.findArtifact("de.westemeyer", "artifact-version-service");

获取特定工件的版本详细信息。

查找具有匹配groupId的工件

找到groupId de.westemeyer的所有工件(精确匹配):

ArtifactVersionCollector.findArtifactsByGroupId("de.westemeyer", true);

查找groupId以de.westemeyer开头的所有工件:

ArtifactVersionCollector.findArtifactsByGroupId("de.westemeyer", false);

按版本号排序结果:

new ArtifactVersionCollector(Comparator.comparing(Artifact::getVersion)).artifactsByGroupId("de.", false);

在工件列表上实现自定义操作

通过提供一个lambda,第一个例子可以像这样实现:

ArtifactVersionCollector.iterateArtifacts(a -> {
    System.out.println(a);
    return false;
});

安装

将这两个标记添加到所有pom.xml文件中,或者可能添加到公司的某个pom主文件中:

<build>
  <plugins>
    <plugin>
      <groupId>de.westemeyer</groupId>
      <artifactId>artifact-version-maven-plugin</artifactId>
      <version>1.1.0</version>
      <executions>
        <execution>
          <goals>
            <goal>generate-service</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

<dependencies>
  <dependency>
    <groupId>de.westemeyer</groupId>
    <artifactId>artifact-version-service</artifactId>
    <version>1.1.0</version>
  </dependency>
</dependencies>

反馈

如果有人能尝试一下这个解决方案,那就太好了。如果能得到你认为解决方案是否符合你的需求的反馈,那就更好了。所以,如果你有任何建议、功能请求、问题,请不要犹豫,在任何github项目上添加一个新问题。

执照

所有的源代码都是开源的,甚至可以免费用于商业产品(MIT许可证)。

引言:因为我记得在几年前回答了这个问题后,我经常提到这个问题,展示了一个动态访问Maven POM信息的动态版本(例如,也在测试期间),今天我发现了一个类似的问题,涉及从另一个模块B访问模块a的Maven信息。

I thought about it for a moment and spontaneously had the idea to use a special annotation, applying it to a package declaration in package-info.java. I also created a multi-module example project on GitHub. I do not want to repeat the whole answer, so please see solution B in this answer. The Maven setup involves Templating Maven Plugin, but could also be solved in a more verbose way using a combination of resource filtering and adding generated sources directory to the build via Build Helper Maven. I wanted to avoid that, so I simply used Templating Maven.