【问题标题】:Ant using Manifestclasspath to run junit ClassNotFoundExceptionAnt使用Manifestclasspath运行junit ClassNotFoundException
【发布时间】:2017-03-17 12:08:49
【问题描述】:

我正在尝试将代码覆盖与 jacoco 集成到由 ant 任务启动的 junit 测试中。 jacoco 强迫我分叉我的 junit 的事实给我带来了一些问题,因为我的类路径很长并且分叉崩溃了。 我正在使用 manifestclasspath 将我的类路径添加到 jar 文件中,并将我的新 jar 作为参数发送给 VM,但它不起作用。我的测试运行,但它们都返回 ClassNotFoundException。 这是我如何配置我的 ant 进程的一部分。

<path refid="bin.classpath"/>

bin.classpath 包含我需要放入 .jar 文件中的所有路径。

<target name="run-unit-tests" depends="init" description="Runs all the unit tests">
  <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
    <classpath path="jacocoant.jar" />
  </taskdef>

  <manifestclasspath property="binjar" jarfile="binManifest.jar">
    <classpath refid="bin.classpath" />
  </manifestclasspath>

  <jar destfile="manifestJars/binManifest.jar">
    <manifest>
      <attribute name="Class-Path" value="${binjar}" />
    </manifest>
  </jar>

  <jacoco:coverage destfile="results/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
    <junit fork="true" reloading="false" showoutput="true">
      <classpath>
        <pathelement path="${projects.dir}/AntProject/manifestJars/binManifest.jar" />
      </classpath>

      <batchtest todir="${test.data.dir}" fork="true">
        <fileset dir="${projects.dir}/ProjectFolder1/src" />
        <fileset dir="${projects.dir}/ProjectFolder2/src" />
      </batchtest>
    </junit>
  </jacoco:coverage>
</target>

如果我在运行 ant 任务时查看控制台日志,我可以看到我的新 .jar 文件是如何发送的:

-classpath''C:\Users\XXX\Project\AntProject\manifestJars\binManifest.jar;

如果我打开创建的 binManifest.jar,我会找到一个 MANIFEST.MF 文件,其中包含我在 Class-Path 属性中的所有路径,格式为: ../../Class1/bin ../../Class2/bin 。 ./../ClassN/bin.但是由于某种原因,我的所有测试都失败了,因为找不到我的课程。我错过了什么?谢谢。

【问题讨论】:

  • 由于路径是相对的 (../../Class1/bin),因此猜测可能是工作目录不正确。
  • 感谢您的回答@Godin。我也这么认为,但是我尝试更改 manifest.mf 内容以放置绝对路径或将我的 .jar 文件更改为根文件夹。对于第一种情况,测试因相同的错误而崩溃,而对于第二种情况,显示的相对路径完全相同

标签: java junit ant classpath jacoco


【解决方案1】:

让我们从没有 JaCoCo 开始 - 下面是一个使用 junit fork="true" 和 manifestclasspath 的 complete and verifiable example。

main/Example.java:

class Example {
  public static void sayHello() {
    System.out.println();
  }
}

test/ExampleTest.java:

public class ExampleTest {
  @org.junit.Test
  public void test() {
    Example.sayHello();
  }
}

build.xml:

<project xmlns:jacoco="antlib:org.jacoco.ant" default="build">
  <target name="build">
    <delete dir="bin" />
    <mkdir dir="bin/main-classes" />
    <mkdir dir="bin/test-classes" />

    <javac target="1.5" debug="true" destdir="bin/main-classes">
      <src path="main" />
    </javac>

    <javac target="1.5" debug="true" destdir="bin/test-classes">
      <src path="test" />
      <classpath>
        <pathelement path="bin/main-classes"/>
        <pathelement path="lib/junit-4.12.jar"/>
        <!-- otherwise "java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing" -->
        <pathelement path="lib/hamcrest-core-1.3.jar"/>
      </classpath>
    </javac>

    <manifestclasspath property="binjar" jarfile="bin/manifest.jar">
      <classpath>
        <pathelement path="bin/main-classes"/>
        <pathelement path="bin/test-classes"/>

        <pathelement path="lib/junit-4.12.jar"/>
        <!-- otherwise "java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing" -->
        <pathelement path="lib/hamcrest-core-1.3.jar"/>
      </classpath>
    </manifestclasspath>

    <jar destfile="bin/manifest.jar">
      <manifest>
        <attribute name="Class-Path" value="${binjar}" />
      </manifest>
    </jar>

    <junit fork="true" showoutput="true">
      <formatter type="brief" usefile="false" />
      <classpath>
        <pathelement path="bin/manifest.jar" />
      </classpath>
      <batchtest>
        <fileset dir="test" includes="**/*Test.java" />
      </batchtest>
    </junit>
  </target>
</project>

根据 Junit 的要求,除了 junit-4.12.jar 之外,请注意 lib/hamcrest-core-1.3.jar 的存在 - 请参阅 https://github.com/junit-team/junit4/wiki/Download-and-Install

让我们通过执行ant来确认它是否正常工作。

在添加 JaCoCo 之后通过添加

<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
  <classpath path="jacocoant.jar" />
</taskdef>

从头开始,

<jacoco:coverage destfile="bin/jacoco.exec" xmlns:jacoco="antlib:org.jacoco.ant">
...
</jacoco:coverage>

junit 附近,最后

<jacoco:report>
  <executiondata>
    <file file="bin/jacoco.exec"/>
  </executiondata>
  <structure name="JaCoCo Ant Example">
    <classfiles>
      <fileset dir="bin/main-classes"/>
    </classfiles>
    <sourcefiles encoding="UTF-8">
      <fileset dir="main"/>
    </sourcefiles>
  </structure>
  <html destdir="bin/report"/>
</jacoco:report>

到最后没什么大不了的。并且ant 的执行将在目录bin/report 中生成报告。

【讨论】:

    猜你喜欢
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多