首页 > 解决方案 > 我想知道如何创建一个包含多个包的 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 文件(一个用于前端,一个用于后端)会产生完全相同的结果。一切正常,直到我将它移动到另一个目录。

我错过了什么,没有看到,无法找到?

标签: javajarexecutable-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.


推荐阅读