我用jar file(附带MANIFEST.MF)导出jar包可以运行 但是用Runnable jar file却说找不到类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我用jar file(附带MANIFEST.MF)导出jar包可以运行 但是用Runnable jar file却说找不到类相关的知识,希望对你有一定的参考价值。

我用jar file(附带MANIFEST.MF)导出jar包可以运行

但是用Runnable jar file却说找不到类

eclipse 中的 jar file 和 runnable jar file的区别如下:
jar file :jar包就是别人已经写好的一些类,然后将这些类进行打包,你可以将这些jar包引入你的项目中,然后就可以直接使用这些jar包中的类和属性以及方法。
JAR(Java ARchive)是将一系列文件合并到单个压缩文件里,就象Zip那样。然而,同Java中其他任何东西一样,JAR文件是跨平台的,所以不必关心涉及具体平台的问题。
涉及因特网应用时,JAR文件显得特别有用。在JAR文件之前,Web浏览器必须重复多次请求Web服务器,以便下载完构成一个“程序片”(Applet)的所有文件。除此以外,每个文件都是未经压缩的。但在将所有这些文件合并到一个JAR文件里以后,只需向远程服务器发出一次请求即可。同时,由于采用了压缩技术,所以可在更短的时间里获得全部数据。
runnable jar file:就是直接可以运行的jar文件。
runnable jar 是在Manifest.MF 文件中指定了 主类,而jar file没有。
参考技术A 我也遇见了类似情况,然后在导出时选择主类和导出路径的界面上【library handing】选项选的[extract required libraries into generated JAR]就行了。。。两年前问题了

从 JAR 中读取 META-INF/MANIFEST.MF [重复]

【中文标题】从 JAR 中读取 META-INF/MANIFEST.MF [重复]【英文标题】:Read META-INF/MANIFEST.MF from JAR [duplicate] 【发布时间】: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());

【问题讨论】:

【参考方案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 版本有一些与此行为相关的更改。谢谢!

以上是关于我用jar file(附带MANIFEST.MF)导出jar包可以运行 但是用Runnable jar file却说找不到类的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中使用 MANIFEST.MF 文件

JAR包中的MANIFEST.MF文件详解以及编写规范

jar包的MANIFEST.MF文件

jar包的MANIFEST.MF文件

Jar文件 META-INF/MANIFEST.MF文件详解

WAR/JAR/EAR 中的 MANIFEST.MF 有啥用?