java - 我想知道如何创建一个包含多个包的 jar 文件
问题描述
我已经阅读了大约 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
它再次运行良好。
为了澄清,jar文件的内容是:
META-INF/
META-INF/MANIFEST.MF
outDir/frontend/timer/
outDir/frontend/timer/Main.class
outDir/backend/
outDir/backend/Activity.class
现在,当我将 jar 复制到另一个文件夹时,它不会运行:
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 文件(一个用于前端,一个用于后端)会产生完全相同的结果。一切正常,直到我将它移动到另一个目录。
我错过了什么,没有看到,无法找到?
解决方案
您已经构建了带有内置的 MANIFEST.MF,Class-Path: outDir/
这意味着在运行时扫描该目录以查找您的打包类。这就是为什么将 outDir 复制到 newDir 解决了一个问题,java 是从 outDir 文件夹而不是 jar 加载类。
Class-Path: outDir/
通过从 MANIFEST.MF中删除条目来解决此问题
下一个问题是你已经用额外的目录路径前缀打包了你的类outDir/
。罐子的正确布局应该是:
META-INF/
META-INF/MANIFEST.MF
frontend/timer/
frontend/timer/Main.class
backend/
backend/Activity.class
outDir
在包含和前端/后端文件夹中构建 jar 的分解结构META-INF/MANIFEST.MF
,然后一步创建 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
.
推荐阅读
- java - 在 Java 中,如何实现一个非泛型接口,该接口具有使用具体类型使用泛型的方法?
- javascript - getAttribute() 和 setAttributeNode() 的问题
- spring-boot - 静态资源未部署到 tomcat-docbase 文件夹 - (IntelliJ 2018 / Spring Boot 2 / Embedded Tomcat)
- mariadb - 接收 SELECT 作为参数的正则表达式只能交替工作(只有奇数次)
- python - 如何计算最大允许的 batch_size?
- javascript - 根据时间戳删除行和单独列中的文本
- docker - Docker-compose:MySQL 更新会破坏数据库
- nginx - 在nginx中返回403时如何显示自定义错误页面?
- tensorflow2.0 - 使用张量输入求解张量流中的 ODE
- flutter - 迭代多个列表并将它们显示在颤动的列表图块中