问题描述
我已经阅读了大约 100 页关于将 java 项目打包成 jar 文件的内容,花了两天时间尝试了所有不同类型的类路径组合,但未能找到解决此问题的方法
package frontend.timer;
import backend.Activity;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world");
Activity myAct = new Activity();
System.out.println(myAct.greeting());
}
}
和....
package backend;
public class Activity {
public String greeting() {
return "Goodby";
}
}
当我编译并运行项目时:
dir /s /B *.java >sources.txt
javac -d outDir @sources.txt
java -classpath outDir frontend.timer.Main
它运行良好。
Main-Class: frontend.timer.Main
Class-Path: outDir/
<blanc line here>
并压缩并使用 jar 文件运行它:
jar.exe cfm timer.jar manifest.mf outDir\frontend\timer outDir\backend
java -jar timer.jar
它再次运行良好。
meta-inf/
meta-inf/MANIFEST.MF
outDir/frontend/timer/
outDir/frontend/timer/Main.class
outDir/backend/
outDir/backend/Activity.class
mkdir newDir
copy timer.jar newDir
java -jar newDir\timer.jar
Error: Could not find or load main class frontend.timer.Main
Caused by: java.lang.classNotFoundException: frontend.timer.Main
只需将 outDir 的内容复制到 newDir 即可解决。但这对我来说没有意义。 创建两个 jar 文件(一个用于前端,一个用于后端)会产生完全相同的结果。一切正常,直到我将其移动到另一个目录。
我错过了什么,看不到,找不到?
解决方法
您已经使用内置的 Class-Path: outDir/
构建了 MANIFEST.MF,这意味着在运行时会扫描该目录以查找您的打包类。这就是为什么将 outDir 复制到 newDir 解决了一个问题,java 是从 outDir 文件夹而不是 jar 加载类。
通过从 MANIFEST.MF 中删除 Class-Path: outDir/
条目来解决此问题
下一个问题是您使用额外的目录路径前缀 outDir/
打包了您的类。 jar 的正确布局应该是:
META-INF/
META-INF/MANIFEST.MF
frontend/timer/
frontend/timer/Main.class
backend/
backend/Activity.class
在包含 outDir
和前端/后端文件夹的 META-INF/MANIFEST.MF
中构建 jar 的分解结构,然后一步创建 jar:
cd outDir
jar cvf ..\timer.jar .
这意味着 jar 具有相同的结构 outDir
以及您使用分解文件夹进行测试的方式。希望这些将是等效的:
java -classpath outDir frontend.timer.Main
java -classpath timer.jar frontend.timer.Main
我建议您在 jar 测试之前也重命名 outDir => outDir.temp 以验证第二个调用是否使用 JAR 而不是 outDir
的内容运行。