如何在Spring Boot应用程序中读取我的META-INF/MANIFEST.MF文件?

Ric*_*ria 15 java manifest.mf spring-boot

我正在尝试从我的Spring Boot Web应用程序(包含在jar文件中)中读取我的META-INF/MANIFEST.MF文件.

我正在尝试以下代码:

        InputStream is = getClass().getResourceAsStream("/META-INF/MANIFEST.MF");

        Properties prop = new Properties();
        prop.load( is );
Run Code Online (Sandbox Code Playgroud)

但显然Spring Boot中有一些东西可以加载一个不同的manifest.mf(而不是我自己位于META-INF文件夹中).

有谁知道如何在Spring Boot应用程序中阅读我的清单应用程序?

更新:经过一些研究后,我注意到使用通常的方式读取manifest.mf文件,在Spring Boot应用程序中,这是正在访问的Jar

org.springframework.boot.loader.jar.JarFile
Run Code Online (Sandbox Code Playgroud)

sam*_*610 17

我使用java.lang.PackageImplementation-Version从清单中读取spring boot中的属性.

String version = Application.class.getPackage().getImplementationVersion();
Run Code Online (Sandbox Code Playgroud)

Implementation-Version应该在中配置该属性build.gradle

jar {
    baseName = "my-app"
    version =  "0.0.1"
    manifest {
        attributes("Implementation-Version": version)
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*eas 6

几乎所有 jar 文件都带有一个清单文件,因此您的代码将返回它可以在 classpath 中找到的第一个文件

你为什么想要清单?它是 Java 使用的文件。将您需要的任何自定义值放在其他地方,例如在您的.properties文件旁边的.class文件中。

更新 2

正如下面的评论中所提到的,不是在问题中,真正的目标是清单中的版本信息。Java 已经在java.lang.Package类中提供了这些信息。

不要试图自己阅读清单,即使你能找到它。

更新 1

请注意,清单文件是不是一个Properties文件。它的结构比这复杂得多。

请参阅JAR 文件规范的 java 文档中的示例。

Manifest-Version: 1.0
Created-By: 1.7.0 (Sun Microsystems Inc.)

Name: common/class1.class
SHA-256-Digest: (base64 representation of SHA-256 digest)

Name: common/class2.class
SHA1-Digest: (base64 representation of SHA1 digest)
SHA-256-Digest: (base64 representation of SHA-256 digest)
Run Code Online (Sandbox Code Playgroud)

如您所见,Name并且SHA-256-Digest发生不止一次。本Properties类无法处理,因为它只是一个Map和键必须是唯一的。

  • @Andreas 问为什么清单?因为 Java 和 Maven 可以轻松并自动地将信息放在那里,例如 Jenkins 内部版本号,这是测试人员报告发现错误的版本时的关键信息。必须尝试将所有内容都塞入实现版本项目的技巧。 (3认同)

abo*_*cic 6

很简单,只需添加

    InputStream is = this.getClass().getClassLoader().getResourceAsStream("META-INF/MANIFEST.MF");

    Properties prop = new Properties();
    try {
        prop.load( is );
    } catch (IOException ex) {
        Logger.getLogger(IndexController.class.getName()).log(Level.SEVERE, null, ex);
    }
Run Code Online (Sandbox Code Playgroud)

为我工作。

注意:

getClass()。getClassLoader()很重要

“ META-INF / MANIFEST.MF”不是“ /META-INF/MANIFEST.MF”

感谢Aleksandar

  • 它可以在其他Java应用程序中工作,但不能在Spring Boot应用程序中工作。在Spring Boot应用程序中,MANIFEST.MF来自在该应用程序使用的所有jar(包括应用程序本身)列表中找到的第一个jar,并使用您的示例,读取的清单来自标准Java库。 (9认同)
  • 你好。是的,它在常规 Java 应用程序中工作,但 Spring Boot 引入了另一个类加载器,它阻止了上面的代码按预期工作。实际上,在调用 getResourceXX 时,spring boot 会在类路径的所有 jar 中搜索与名称匹配的第一个资源。 (2认同)