【问题标题】:Java ignoring Class-Path entry in jar file's manifestJava忽略jar文件清单中的类路径条目
【发布时间】:2015-11-20 11:23:45
【问题描述】:

我搜索了互联网,也搜索了stackoverflow,发现很多帖子都在问这个问题,但从来没有一个具体的答案。


简短版本是:我有一个 jar 文件,它引用清单中的其他 jar 文件。然后我使用 java -jar test.jar 运行 jar 文件,但它不会将 jar 依赖项添加到类路径中。


长版:我做了一个小实验,以确认我的项目没有什么特别之处。我在 Eclipse 中创建了一个简单的 Java 项目,只有 1 个类。这个类所做的只是将类路径写入标准输出:

package test;

import java.net.URL;
import java.net.URLClassLoader;

public class Test {
  public static void main(String[] args){
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    URL[] urls = ((URLClassLoader)cl).getURLs();
    for(URL url: urls){
      System.out.println("CP: "+url.getFile());
    }
  }
}

然后我创建了一个“lib”文件夹并将一个随机的 jar 文件放入其中并将其添加到类路径中。文件夹结构现在如下所示:

Test
|- src/test/Test.java
|- lib/mysql-connector-java-3.1.14-bin.jar

现在当我从 Eclipse 运行它时,我得到以下输出:

CP: /home/username/workspace/Test/bin/
CP: /home/username/workspace/Test/lib/mysql-connector-java-3.1.14-bin.jar

好的,现在我使用 Eclipse 将项目导出到可运行的 jar 中。我选择“将所需的库复制到生成的 jar 旁边的子文件夹中”选项。

这将创建以下结构:

/tmp/Test
|- test.jar
|- test_lib/mysql-connector-java-3.1.14-bin.jar

如果我查看 Eclipse 创建的 Test.jar,它看起来像这样:

test.jar
|- test/Test.class
|- META-INF/MANIFEST.MF

MANIFEST.MF 的内容是:

Manifest-Version: 1.0
Class-Path: . test_lib/mysql-connector-java-3.1.14-bin.jar
Main-Class: test.Test

是的,在 Main-Class 属性之后有一个空行(我提到这一点是因为有些人在网上发布了原因可能是末尾缺少换行符)。

所以,一切看起来都很好。我用 java -jar test.jar 运行它并得到以下输出:

CP: /tmp/Test/test.jar

所以类路径只包含我想要运行的 jar 文件。 MANIFEST 中的 Class-Path: 属性被完全忽略。 如果我使用 java -cp test.jar test.Test

运行它,也会发生同样的事情

如何正确使用 MANIFEST.MF 中的 Class-Path 属性?我这辈子都想不通。特别是因为 -cp 和 -jar 不兼容,我不知道如何在使用 -jar 参数的同时指定类路径。

非常感谢。


还有几件事我可以提前回答:

  • “最后一行之后是否有换行符?” - 是的
  • “会不会是 Eclipse 使 MANIFEST.MF 格式错误?” - 可能是,但是当我用蚂蚁制作罐子时我遇到了同样的问题。因此,如果 eclipse 和 ant 都使 manifest 格式错误,我不知道应该如何格式化它。
  • “您尝试过哪些平台、Java 版本?” - 我在 Windows 10 上试用过 Java8,在 Fedora Linux 上试用过 Java6、Java7 和 Java8。

【问题讨论】:

  • 如果您只是尝试加载 jar 中的类,而不是显示类路径,会发生什么情况?例如,Class.forName("com.mysql.jdbc.Driver")
  • 该死的……这行得通。这意味着我的其他项目的问题在其他地方,因为我得到了 ClassNotFoundExceptions
  • 我不明白 Class-Path 行上句号的目的。此外,尝试简单地将两个 jar 放在同一个目录中,并使 Class Path 行如下所示:Class-Path: mysql-connector-java-3.1.14-bin.jar。只要您有一个能够编辑清单的归档应用程序,您就不必重新导出项目。
  • 是的,我也想知道那个时期。这就是eclipse生成它的方式。我可以使用 file-roller 更改清单。但在 JB Nizet 的帮助下,我意识到我的实验设置错误。如果我尝试从 jar 文件中实例化任何内容,它实际上可以工作。所以一切正常。现在我只需要弄清楚为什么它在我的其他项目中不起作用......

标签: java eclipse jar classpath manifest


【解决方案1】:

好的,感谢 JB Nizet 的评论,我发现一切正常。它不会打印出类路径,但我可以从库中访问这些类。所以我的实验设置错误。这对我来说是个坏消息,因为我的其他项目仍然无法运行,而且在这里发布太复杂了。

【讨论】:

  • 我只是通过将其与测试进行比较来确保您正确引用了该 jar,或者甚至将测试类放入您的其他项目的 jar 并运行它,只是为了确保。然后尝试从外部 jar 引用类的不同方法。我没有看到你的代码,但如果我不得不猜测,那就是问题所在。
  • 感谢您的评论。我现在找到了罪魁祸首。在我的另一个项目(jar 是用 ant 创建的)中,jar 文件中存在一个“INDEX.LIST”文件。我以前读过这个,但由于我(错误地)认为我的测试项目也不起作用并且它没有索引文件,所以我没有进一步调查。
猜你喜欢
  • 2023-03-04
  • 1970-01-01
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多