一个罐子里的NoClassDefFoundError

问题描述 投票:0回答:1

上下文

为了学习使用蚂蚁,我做了一个小的概念证明项目:

我创建了一个小的JAR文件,只包含一个可以在这里看到的类:

public class Dummy {

    private String name;

    public Dummy(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

我制作了一个名为lib/dummy.jar的JAR。这是它的清单:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.5
Created-By: 1.8.0_232-b09 (Oracle Corporation)
Class-Path: 

项目

现在,我想在看起来像这样的主类中使用该JAR:

public class Main {
    public static void main(String[] args) {
        Dummy f = new Dummy("Hello, World!");
        System.out.println(f.getName());
    }
}

我可以毫无问题地进行编译(如果我在类路径中包含了JAR)。

然后,我尝试制作该主类的JAR。 JAR包含以下内容:

META-INF/
|- MANIFEST.MF
Main.class
dummy.jar

清单包含:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.5
Created-By: 1.8.0_232-b09 (Oracle Corporation)
Main-Class: Main
Class-Path: dummy.jar

JAR已成功创建。

问题

如果我尝试运行JAR,我会得到Exception in thread "main" java.lang.NoClassDefFoundError: Dummy

代码应该正常工作,因为如果在运行时在类路径中包含我的初始dummy.jar,则一切正常。 (java -cp build/jar/run-me.jar:lib/dummy.jar Main

为什么我自己全部运行JAR时不起作用?

build.xml

如果有用,这是我的build.xml(评论中高兴地接受了改进):

<project default="all">
    <path id="build.classpath">
        <fileset dir="lib">
            <include name="**/*.jar" />
        </fileset>
    </path>
    <pathconvert property="mf.classpath" pathsep=" ">
        <path refid="build.classpath" />
        <flattenmapper />
    </pathconvert>

    <target name="all" depends="compile,jar,run" />

    <target name="compile">
        <mkdir dir="build/classes" />
        <javac srcdir="src" destdir="build/classes" includeantruntime="false">
            <classpath>
                <fileset dir="lib">
                    <include name="**/*.jar" />
                </fileset>
            </classpath>
        </javac>
    </target>

    <target name="jar">
        <mkdir dir="build/jar" />
        <jar destfile="build/jar/run-me.jar" basedir="build/classes">
            <manifest>
                <attribute name="Main-Class" value="Main" />
                <attribute name="Class-Path" value="${mf.classpath}" />
            </manifest>
            <path id="build.classpath">
                <fileset dir="lib">
                    <include name="**/*.jar" />
                    <include name="**/*.zip" />
                </fileset>
            </path>
        </jar>
    </target>

    <target name="run">
        <java jar="build/jar/run-me.jar" fork="true"></java>
    </target>

    <target name="clean">
        <delete dir="build" />
    </target>
</project>
java jar ant lib
1个回答
0
投票
Class-Path: dummy.jar表示它将在

相同文件夹中寻找dummy.jar作为run-me.jar。它不查找inside run-me.jar

由于run-me.jar位于build/jar中,而dummy.jar位于lib中,因此您需要指定Class-Path: ../../lib/dummy.jar才能使它工作。

最好保留Class-Path: dummy.jar并将两个jar文件在运行时都放在同一文件夹中。

© www.soinside.com 2019 - 2024. All rights reserved.