蚂蚁+ JUnit4 ClassDefNotFoundException - 类路径问题?

发布于 2024-08-12 17:38:06 字数 5033 浏览 4 评论 0原文

[编辑]已解决,我作为蚂蚁初学者犯的小错误。在测试目标中,它需要是 而不是 >。这显然覆盖了我定义的类路径属性。这清楚地表明 ant 无法找到该库。请注意:rtfm![/Edit]

首先,我正在使用 Ant 1.7.1 和 JUnit 4.7。

这让我困扰了好几个小时。我有一个 Netbeans 项目 (6.7.1)。在项目中我添加了测试源,现在我想从 ant 调用测试。所以我有以下 ant 文件:

<?xml version="1.0" encoding="UTF-8"?>

<project name="LiveStreamClient" default="clean-build" basedir=".">
<description>Builds, tests, and runs the project.</description>
<property name="src.dir"        value="src"/>
<property name="build.dir"      value="build"/>
<property name="classes.dir"    value="${build.dir}/classes"/>
<property name="test.classes.dir" value="${build.dir}/classes/livestreamclient"/>
<property name="jar.dir"        value="${build.dir}/jar"/>    
<property name="report.dir"     value="${build.dir}/junitreport"/>
<property name="lib.dir"        value="lib"/>
<property name="test.dir"       value="test"/>

<property name="main.class"     value="livestreamclient.Main"/>
<property name="VERSION"        value="0.1."/>

<path id="my.classpath">
    <fileset dir="${lib.dir}" includes="**/*.jar"/>
    <pathelement location="${classes.dir}"/>
   <!-- <pathelement location="${test.classes.dir}" />
    <pathelement location="${test.dir}" /> -->
</path>

<!-- increment the build number -->    
<buildnumber/>

<!-- clean deletes complete build directory -->
<target name="clean">
    <delete dir="${build.dir}"/>
</target>

<!-- compile classes -->
<target name="compile">
    <mkdir dir="${classes.dir}"/>
    <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
    <!-- <javac srcdir="${test.dir}" destdir="${classes.dir}"/> -->
</target>

<!-- pack as java archive -->
<target name="jar" depends="compile">
    <mkdir dir="${jar.dir}"/>
    <jar destfile="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" basedir="${classes.dir}">
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>

<!-- run the test classes -->    
<target name="test" depends="jar">
    <mkdir dir="${report.dir}"/>
    <junit printsummary="yes">
        <classpath id="my.classpath"/>
        <formatter type="plain"/>
        <batchtest fork="yes" todir="${report.dir}">
            <fileset dir="${test.dir}">
                <include name="**/*Test*"/>
            </fileset>
        </batchtest>
    </junit> 
</target>

<!-- JUnit testing report -->    
<target name="junitreport">
    <junitreport todir="${report.dir}">
        <fileset dir="${report.dir}" includes="Test-*.xml"/>
        <report todir="${report.dir}"/>
    </junitreport>
</target>

<!-- run the jar -->
<target name="run" depends="jar">
    <java jar="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" fork="true"/>
</target>

<target name="commit" depends="run">
  <exec executable="hg">
    <arg value="ci"/>
    <arg value="-m"/>
    <arg value="TESTCOMMIT"/>
  </exec>
</target>


<!-- default target -->
<target name="clean-build" depends="clean,jar"/>

<target name="main" depends="clean,run"/>

我的方法是对 test.dir 文件夹中的(更多)测试文件进行批量测试,到目前为止,该文件夹仅包含以下测试类:

package livestreamclient.modeltest;

import org.junit.*;
import static org.junit.Assert.*;
import livestreamclient.model.*;

public class LiveStreamModelTest {
    @Test
    public void testCreation() {
        LiveStreamModel model = new LiveStreamModel();
        assertFalse(1 == 2);
    }

}

测试文件位于 test 文件夹中,而实际源是在 src 文件夹中,因为这就是 NetBeans 默认处理结构的方式。

Ant 为 JUnit 任务中的测试文件提供了 ClassDefNotFoundException...但该类位于所需的文件夹中。我在这里遗漏了一些概念吗?

编辑:

在 junit 报告中创建的异常跟踪如下:

Testsuite: livestreamclient.modeltest.LiveStreamModelTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec

Caused an ERROR
livestreamclient.modeltest.LiveStreamModelTest
java.lang.ClassNotFoundException: livestreamclient.modeltest.LiveStreamModelTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)

[Edit] Solved, small mistake done by me being an ant beginner. In the test target, it needs to be <classpath refid="my.classpath"/> instead of <classpath id="my.classpath"/>. That obviously overwrote my defined classpath property. That makes it clear that ant is not able to find the library. Note to me: rtfm![/Edit]

First things first: I'm using Ant 1.7.1 and JUnit 4.7.

This bothers me for quite a fewhours now. I've got a Netbeans project (6.7.1). In the project I added test sources, now I would like to do invoke the testing from ant. So I've got the following ant file:

<?xml version="1.0" encoding="UTF-8"?>

<project name="LiveStreamClient" default="clean-build" basedir=".">
<description>Builds, tests, and runs the project.</description>
<property name="src.dir"        value="src"/>
<property name="build.dir"      value="build"/>
<property name="classes.dir"    value="${build.dir}/classes"/>
<property name="test.classes.dir" value="${build.dir}/classes/livestreamclient"/>
<property name="jar.dir"        value="${build.dir}/jar"/>    
<property name="report.dir"     value="${build.dir}/junitreport"/>
<property name="lib.dir"        value="lib"/>
<property name="test.dir"       value="test"/>

<property name="main.class"     value="livestreamclient.Main"/>
<property name="VERSION"        value="0.1."/>

<path id="my.classpath">
    <fileset dir="${lib.dir}" includes="**/*.jar"/>
    <pathelement location="${classes.dir}"/>
   <!-- <pathelement location="${test.classes.dir}" />
    <pathelement location="${test.dir}" /> -->
</path>

<!-- increment the build number -->    
<buildnumber/>

<!-- clean deletes complete build directory -->
<target name="clean">
    <delete dir="${build.dir}"/>
</target>

<!-- compile classes -->
<target name="compile">
    <mkdir dir="${classes.dir}"/>
    <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
    <!-- <javac srcdir="${test.dir}" destdir="${classes.dir}"/> -->
</target>

<!-- pack as java archive -->
<target name="jar" depends="compile">
    <mkdir dir="${jar.dir}"/>
    <jar destfile="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" basedir="${classes.dir}">
        <manifest>
            <attribute name="Main-Class" value="${main.class}"/>
        </manifest>
    </jar>
</target>

<!-- run the test classes -->    
<target name="test" depends="jar">
    <mkdir dir="${report.dir}"/>
    <junit printsummary="yes">
        <classpath id="my.classpath"/>
        <formatter type="plain"/>
        <batchtest fork="yes" todir="${report.dir}">
            <fileset dir="${test.dir}">
                <include name="**/*Test*"/>
            </fileset>
        </batchtest>
    </junit> 
</target>

<!-- JUnit testing report -->    
<target name="junitreport">
    <junitreport todir="${report.dir}">
        <fileset dir="${report.dir}" includes="Test-*.xml"/>
        <report todir="${report.dir}"/>
    </junitreport>
</target>

<!-- run the jar -->
<target name="run" depends="jar">
    <java jar="${jar.dir}/${ant.project.name}${VERSION}${build.number}.jar" fork="true"/>
</target>

<target name="commit" depends="run">
  <exec executable="hg">
    <arg value="ci"/>
    <arg value="-m"/>
    <arg value="TESTCOMMIT"/>
  </exec>
</target>


<!-- default target -->
<target name="clean-build" depends="clean,jar"/>

<target name="main" depends="clean,run"/>

My approach is to batchtest the (more to come) testfiles in the test.dir folder, which holds only the following test class so far:

package livestreamclient.modeltest;

import org.junit.*;
import static org.junit.Assert.*;
import livestreamclient.model.*;

public class LiveStreamModelTest {
    @Test
    public void testCreation() {
        LiveStreamModel model = new LiveStreamModel();
        assertFalse(1 == 2);
    }

}

The test file resides in the test folder, whereas the actual source is within the src folder, as that is how NetBeans handles the structure by default.

Ant gives me ClassDefNotFoundException for the test file in the JUnit task... But the class is in the desired folder. Am I missing something conceptionally here?

EDIT:

The exception trace created in the junit report is the following:

Testsuite: livestreamclient.modeltest.LiveStreamModelTest
Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec

Caused an ERROR
livestreamclient.modeltest.LiveStreamModelTest
java.lang.ClassNotFoundException: livestreamclient.modeltest.LiveStreamModelTest
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

傾旎 2024-08-19 17:38:06

ClassDefNotFoundError 意味着类加载器可以加载类 X 但无法实例化它,因为它无法加载类 X 所依赖的类。

因此,就您的情况而言,请在运行测试时检查 JUnit 4 的 JAR(LiveStreamModelTest 所依赖的类)是否确实位于类路径中。另请检查您是否使用 Ant 1.7+(据我所知这是 JUnit 4 所必需的)。

A ClassDefNotFoundError means that the classloader can load a class X but cannot instantiate it because it cannot load the classes that class X depends on.

So, in your case, check that JUnit 4's JAR (the classes LiveStreamModelTest depends on) is really on the classpath when running tests. Also check that you are using Ant 1.7+ (which is required for JUnit 4 AFAIK).

坚持沉默 2024-08-19 17:38:06

也有可能是测试类本身有问题;例如,如果静态初始化程序中抛出异常,您将得到 ClassDefNotFoundError。尝试通过其他方式(调试器、测试代码)验证该类是否按预期工作。

It's also possible that there is something wrong with the test class itself; for example if there is an exception thrown in a static initializer the you will get a ClassDefNotFoundError. Try to verify through some other means (debugger, test code) that the class is working as expected.

好听的两个字的网名 2024-08-19 17:38:06

尝试将 JUnit 4 JAR 添加到 Ant /lib 目录。

Try adding the JUnit 4 JAR to your Ant /lib directory.

感情洁癖 2024-08-19 17:38:06

尝试添加这样的路径标签...这解决了我的问题。

<path id="classpath" description="Classpath do Projeto">
    <fileset dir="${LIB}">
        <include name="**/*.jar" />
        <exclude name="**/.SVN/*.*"/>
    </fileset>
</path>

Try adding the path tag like this... this solved my problem.

<path id="classpath" description="Classpath do Projeto">
    <fileset dir="${LIB}">
        <include name="**/*.jar" />
        <exclude name="**/.SVN/*.*"/>
    </fileset>
</path>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文