Java忽略jar文件清单中的Class-Path条目

Ren*_*der 5 java eclipse jar manifest classpath

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


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


加长版:我做了一个小实验,以确认它对我的项目来说不是什么特别的事情。我在eclipse中创建了一个简单的Java项目,只有一个类。该类所做的只是将类路径写入std-out:

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());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Test
|- src/test/Test.java
|- lib/mysql-connector-java-3.1.14-bin.jar
Run Code Online (Sandbox Code Playgroud)

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

CP: /home/username/workspace/Test/bin/
CP: /home/username/workspace/Test/lib/mysql-connector-java-3.1.14-bin.jar
Run Code Online (Sandbox Code Playgroud)

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

这将创建以下结构:

/tmp/Test
|- test.jar
|- test_lib/mysql-connector-java-3.1.14-bin.jar
Run Code Online (Sandbox Code Playgroud)

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

test.jar
|- test/Test.class
|- META-INF/MANIFEST.MF
Run Code Online (Sandbox Code Playgroud)

MANIFEST.MF的内容是:

Manifest-Version: 1.0
Class-Path: . test_lib/mysql-connector-java-3.1.14-bin.jar
Main-Class: test.Test
Run Code Online (Sandbox Code Playgroud)

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

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

CP: /tmp/Test/test.jar
Run Code Online (Sandbox Code Playgroud)

因此,类路径包含我要运行的jar文件。清单中的Class-Path:属性被完全忽略。如果我使用java -cp test.jar test.Test运行它,也会发生同样的事情

如何正确使用MANIFEST.MF中的Class-Path属性?我无法终生解决。特别是因为-cp和-jar不兼容,所以我不知道如何同时使用-jar参数来指定类路径。

非常感谢。


我可以提前回答几件事:

  • “最后一行之后是否有换行符?” -是的
  • “是MANIFEST.MF的月食畸形吗?” -可以,但是当我用蚂蚁做罐子时,我遇到了同样的问题。因此,如果日食和蚂蚁都使清单错误,我不知道应该如何格式化它。
  • “您尝试过什么平台,Java版本?” -我在Windows 10上尝试过Java8,在Fedora Linux上尝试过Java6,Java7和Java8。

Ren*_*der 1

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