第一次发帖,对于我的格式不佳深表歉意。我有一个在eclipse中开发的java程序。我将程序导出为 jar (myJar.jar),然后将程序所依赖的所有外部 jar 放入名为lib的文件夹中,该文件夹与 myJar.jar 位于同一位置。为了设置我的类路径,我有一个具有以下格式的清单文件:
Main-Class: exe.myMain
Class-Path: lib/jar_1.jar lib/jar_2.jar ... lib/jar_n.jar
Manifest-Version: 1.0
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试使用“java -jar myJar.jar”运行程序时, lib中的 jar 中的类不会被加载(我收到 ClassNotFoundException)。我在程序中使用以下代码来打印类路径:
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url:urls){
System.out.println(url.getFile());
}
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,类路径只是“myJar.jar”。
我有两个问题:
1.) 上面的代码实际上在运行时为我提供了 JRE 的类路径,还是只是为我提供了主类的地址?
2.) 鉴于上面的代码确实在运行时为我提供了 JRE 的类路径,我做错了什么吗?
请随时询问更多信息,我很乐意提供您所需的信息。
你正在做的事情听起来是正确的。
由于某种原因,Class-Path在检查类路径时清单中的条目不会显示(例如,此处和此处;这些示例使用该属性"java.class.path",但我的测试显示其ClassLoader.getURLs()行为相同)。不过,仍然应该搜索它的类。我不知道如何获取包含Class-Path清单中条目的真实类路径。
META-INF/MANIFEST.MF我要检查的第一件事是里面的文件是否myJar.jar与您创建的清单相匹配。您可以myJar.jar通过将其重命名为具有.zip文件扩展名来打开。
我尝试复制您的问题,但其中的类lib/jar_1.jar已为我加载,因此如果META-INF/MANIFEST.MF正确,我将详细描述我所做的事情,以便您可以找到我们正在做的不同事情。
编辑:
以下是我使用的步骤:
创建一个名为“experiment”的新目录。下面的步骤都是在该目录下完成的。
创建名为“jar_1”、“lib”和“exe”的新目录
在目录“jar_1”中创建一个名为“ClassInJar1.java”的文件,其中包含以下内容:
package jar_1;
public class ClassInJar1 {
public static void method() {
System.out.println("Hello from ClassInJar1");
}
}
Run Code Online (Sandbox Code Playgroud)跑步javac jar_1/ClassInJar1.java
跑步jar cf lib/jar_1.jar jar_1/ClassInJar1.class
在目录“exe”中创建一个名为“myMain.java”的文件,其中包含以下内容:
package exe;
import java.net.*;
import jar_1.ClassInJar1;
public class myMain {
public static void main(String[] args) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
System.out.println(url.getFile());
}
ClassInJar1.method();
}
}
Run Code Online (Sandbox Code Playgroud)跑步javac exe/myMain.java
在“experiment”目录中创建一个名为“manifest”的文件,其中包含以下内容:
package jar_1;
public class ClassInJar1 {
public static void method() {
System.out.println("Hello from ClassInJar1");
}
}
Run Code Online (Sandbox Code Playgroud)
跑步jar cfm myJar.jar manifest exe/myMain.class
跑步java -jar myJar.jar
输出:
package exe;
import java.net.*;
import jar_1.ClassInJar1;
public class myMain {
public static void main(String[] args) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
System.out.println(url.getFile());
}
ClassInJar1.method();
}
}
Run Code Online (Sandbox Code Playgroud)