JAR清单中的绝对路径与相对路径名的区别

4
我希望在固定位置引用一个jar文件,以供多个可执行的jar文件使用,而不是在每个可执行文件中包含该jar。我有以下的设置,它可以正常工作:
commons-math3-3.6.1.jar 存在于 testgradle 目录下。TestGradle.jar 包含主方法,存在于 testgradle/build/libs 目录下。
从 testgradle/build/libs 目录下运行:
java -jar TestGradle.jar

一切都运行良好。TestGradle.jar中的清单包含:

Manifest-Version: 1.0
Class-Path: ../../commons-math3-3.6.1.jar
Main-Class: com.spgxyz.test.testg

但是我希望使用绝对路径来引用commons-math3-3.6.1.jar,以便可执行的jar文件,比如TestGradle.jar,可以从任何目录中使用它。然而,如果我更改TestGradle.jar清单文件以包含完整的路径:

Manifest-Version: 1.0
Class-Path: C:\Users\Admin\workspace\TestGradle\commons-math3-3.6.1.ja
 r
Main-Class: com.spgxyz.test.testg

接着是以下命令:

java -jar TestGradle.jar

从testgradle/build/libs目录运行会产生以下结果:

Error: Could not find or load main class com.spgxyz.test.testg
Caused by: java.lang.ClassNotFoundException: com.spgxyz.test.testg

我尝试了多种编辑清单的方法来解决这个问题,例如:

Manifest-Version: 1.0
Class-Path: . C:\Users\Admin\workspace\TestGradle\commons-math3-3.6.1.
 jar
Main-Class: com.spgxyz.test.testg

Manifest-Version: 1.0
Class-Path: TestGradle.jar C:\Users\Admin\workspace\TestGradle\commons
 -math3-3.6.1.jar
Main-Class: com.spgxyz.test.testg

这两个都会产生相同的错误。如果有人能够解释一下这里发生了什么,我将非常感激。运行在Windows上。

1个回答

4

Class-Path属性被解释为URL列表,因此,要使用绝对路径(在这里用URL表示),它应该以模式开头并使用正斜杠。

请尝试以下内容:

Class-Path: file:///C:/Users/Admin/workspace/TestGradle/commons-math3-3.6.1.jar

1
Roman Puchkovskiy发布的解决方案有效,但是我想知道为什么在阅读了很多文章之后,我没有找到任何可以引导我使用那个解决方案的东西。例如,在Oracle文档中(https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html),有几个地方似乎使用了绝对路径,例如c:\ java \ ...。 - stegzzz
1
在您发布链接的文档中,他们谈到了文件路径(您将其提供给-cp命令行参数),而文件路径可以包含反斜杠。但是正如在这里https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#classpath中所看到的那样,清单的`Class-Path`元素包含**URLs**。 URL有自己的规则,在那里反斜杠不好用。此外,开头的C:可能会被解释为URL协议,因此我们必须明确使用file:/// - Roman Puchkovskiy
2
请注意,该链接明确且反复说明URL必须是相对URL。绝对URL(如此类)可能会起作用,但不受官方支持。更好的解决方案是将commons-math3-3.6.1.jar复制到包含每个.jar文件的目录中,并在清单中放置“Class-Path:commons-math3-3.6.1.jar”。 - VGR
但是我参考的链接清楚而又反复地在类路径中使用绝对路径,很容易看出这可能会导致混淆。例如,在这里它声明:“manifest可以定义一个JAR类路径,这进一步扩展了类路径...”,这并不立即表明在清单中定义的类路径有不同的规则。 - stegzzz
1
在这个链接的底部 https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#classpath 中写道:“目前,出于安全原因,URL必须相对于JAR文件的代码库。”。我怀疑如果您设法让绝对路径起作用,就不应该认为它将继续工作或在所有平台上都能正常工作。 - Dave L.
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接