【发布时间】: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