【问题标题】:Read META-INF/MANIFEST.MF from JAR [duplicate]从 JAR 中读取 META-INF/MANIFEST.MF [重复]
【发布时间】:2018-07-23 16:51:09
【问题描述】:

这很奇怪。我尝试从应用程序本身读取 META-INF/MANIFEST.MF:

URL url = getClass().getResource("/META-INF/MANIFEST.MF");

但 MANIFEST.MF 是另一个:

jar:file:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar!/META-INF/MANIFEST.MF

这在过去有效,但现在它将它定位在另一个 JAR 中!非常非常奇怪。

更新

按照 haraldK 的建议进行了尝试,但返回的枚举为空,因此没有打印任何内容:

try {
    Enumeration<URL> manifests = getClass().getClassLoader().getResources("/META-INF/MANIFEST.MF");

    while(manifests.hasMoreElements()) {
        URL url = manifests.nextElement();
        System.out.println("Es: > " + url);
    }
} catch (Exception e) {
    System.err.println(e.getMessage());
}

【问题讨论】:

    标签: java


    【解决方案1】:

    根据类加载器和类路径上 JAR 的顺序,这只是正常行为。由于/META-INF/MANIFEST.MF 有多个实例,您实际获得的实例取决于类加载器(加载当前类,由代码中的getClass() 返回)。

    相反,您可以使用ClassLoader.getResouces(String),它将为您提供所有清单的枚举:

    Enumeration<URL> manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
    

    从该枚举中,您可以找到正确的。

    另一种选择是使用Package 类,这将使您可以轻松地从清单中访问您的类/包的信息:

    Package myPackage = getClass().getPackage();
    myPackage.getImplementationTitle();
    myPackage.getImplementationVersion();
    myPackage.getImplementationVendor();
    

    【讨论】:

    • 按建议尝试,但返回的枚举为空,因此没有打印任何内容:-\
    • 尝试跳过前导斜杠(即getClassLoader().getResources("META-INF/MANIFEST.MF"))。可能是复制/粘贴错误。
    • 没有斜杠会返回一堆 URL,但它们都没有引用想要的 JAR(一些 JDK 库,一些 Maven 依赖项,...):/
    • 这与 IntelliJ 有关,因为如果我从命令行执行应用程序,资源会出现在正确的 JAR 中(第二个条目,因为第一个是来自 JDK 的 jfxrt.jar)。谢谢!
    【解决方案2】:

    GetClass().getResource 行为取决于类加载器的实现:https://docs.oracle.com/javase/8/docs/technotes/guides/lang/resources.html 也许您的应用程序有额外的类加载器?

    类似的问题在这里:Reading my own Jar's Manifest

    【讨论】:

    • 好吧,它在几周前就奏效了。也许新的 Java 8 版本有一些与此行为相关的更改。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 2011-05-19
    • 2020-03-06
    • 2012-06-10
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多