在运行时获取Maven工件版本

Arm*_*and 166 java maven-2

我注意到在Maven工件的JAR中,project.version属性包含在两个文件中:

META-INF/maven/${groupId}/${artifactId}/pom.properties
META-INF/maven/${groupId}/${artifactId}/pom.xml
Run Code Online (Sandbox Code Playgroud)

是否有推荐的方法在运行时读取此版本?

Joa*_*uer 251

您不需要访问特定于Maven的文件来获取任何给定库/类的版本信息.

您只需使用getClass().getPackage().getImplementationVersion()获取存储在.jar文件中的版本信息即可MANIFEST.MF.幸运的是Maven很聪明不幸的是Maven默认情况下也没有将正确的信息写入清单!

代替一个具有修改<archive>的构造元件maven-jar-plugin设置addDefaultImplementationEntriesaddDefaultSpecificationEntriestrue,这样的:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>                   
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)

理想情况下,这种配置应该放在公司pom或其他基地.

<archive>可以在Maven Archive文档中找到该元素的详细文档.

  • 遗憾的是,并非每个类加载器似乎都从清单文件加载这些属性(我记得在这种情况下遇到Tomcat问题). (4认同)
  • 不幸的是,如果项目是从Eclipse运行或使用"mvn exec:java",这不起作用. (3认同)

小智 74

为了跟进上面的答案,对于一个.war工件,我发现我必须应用等效配置maven-war-plugin,而不是maven-jar-plugin:

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1</version>
    <configuration>
        <archive>                   
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
        </archive>
    </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)

这增加了版本信息MANIFEST.MF在项目.jar(包括在WEB-INF/lib.war)

  • 当我尝试这个时,我的结果总是为"null",尽管war文件中的MANIFEST.MF包含正确的信息. (8认同)
  • <archiveClasses> true </ archiveClasses>在我的情况下导致错误.但问题得到了解决http://stackoverflow.com/questions/14934299/how-to-get-package-version-at-running-tomcat (3认同)
  • <archiveClasses> true </ archiveClasses>似乎无关 (2认同)

mys*_*mic 27

这是从pom.properties获取版本的方法,后退到从清单中获取它

public synchronized String getVersion() {
    String version = null;

    // try to load from maven properties first
    try {
        Properties p = new Properties();
        InputStream is = getClass().getResourceAsStream("/META-INF/maven/com.my.group/my-artefact/pom.properties");
        if (is != null) {
            p.load(is);
            version = p.getProperty("version", "");
        }
    } catch (Exception e) {
        // ignore
    }

    // fallback to using Java API
    if (version == null) {
        Package aPackage = getClass().getPackage();
        if (aPackage != null) {
            version = aPackage.getImplementationVersion();
            if (version == null) {
                version = aPackage.getSpecificationVersion();
            }
        }
    }

    if (version == null) {
        // we could not compute the version so use a blank
        version = "";
    }

    return version;
} 
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于从jar运行应用程序时.如果从exec-maven-plugin(例如Netbeans)运行,则资源为null. (3认同)
  • 把它放在静态初始化块中. (2认同)

dar*_*ilz 12

如果您碰巧使用 Spring Boot,则可以使用BuildProperties类。

以我们的 OpenAPI 配置类中的以下代码片段为例:

@Configuration
@RequiredArgsConstructor // <- lombok
public class OpenApi {

    private final BuildProperties buildProperties; // <- you can also autowire it

    @Bean
    public OpenAPI yourBeautifulAPI() {
        return new OpenAPI().info(new Info()
            .title(buildProperties.getName())
            .description("The description")
            .version(buildProperties.getVersion())
            .license(new License().name("Your company")));
    }
}
Run Code Online (Sandbox Code Playgroud)


Chr*_*Sim 8

我知道这是一个很晚的答案,但我想分享我根据链接所做的事情:

我将以下代码添加到 pom.xml 中:

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

这个建议控制器为了获取版本作为模型属性:

import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.info.BuildProperties;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

@ControllerAdvice
public class CommonControllerAdvice
{
       @Autowired
       BuildProperties buildProperties;
    
       @ModelAttribute("version")
       public String getVersion() throws IOException
       {
          String version = buildProperties.getVersion();
          return version;
       }
    }
Run Code Online (Sandbox Code Playgroud)


千木郷*_*千木郷 6

maven-assembly-plugin用于我的 maven 包装。在Joachim Sauer 的回答中使用Apache Maven Archiver也可以:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution .../>
    </executions>
</plugin>
Run Code Online (Sandbox Code Playgroud)

因为archiever是maven共享组件之一,它可以被多个maven构建插件使用,如果引入两个或多个插件,包括archive里面的配置,也会产生冲突。