2012-10-05 137 views
6

我意识到存在很多与this one类似的问题,但是在阅读了大多数问题之后,我似乎遇到了同样的问题,但出于不同的原因。Ant JUnit ClassNotFoundException

我在我的Ant构建中运行了一个<junit>任务,我得到一个ClassNotFoundException。在大多数类似相关的问题中(比如上面的问题),结果是作者的各种程度都没有正确配置JUnit类路径。虽然它对我来说可能非常相似,但对于其他任何问题的建议都没有为我工作。

我的项目目录结构:

MyProject/ 
    src/main/java/ 
     FakeObject.java 
     ...the rest of my Java main source 
    src/test/java 
     FakeObjectUnitTest.java 
     ...the rest of my Java test source 
    bin/main 
     FakeObject.class 
     ...the rest of main Java binaries 
    bin/test 
     FakeObjectUnitTest.class 
     ...the rest of main Java binaries 
    lib/main 
     ...my main dependencies 
    lib/test 
     junit-4.10.jar 
     hamcrest-1.1.jar 
     ...the rest of my test dependencies 
    gen/reports 
     ...where JUnit should be placing all test reports 
    build/ 
     build.xml 
     build.properties 

src/test/java/FakeObjectUnitTest.java

// Package and imports omitted 

public class FakeObjectUnitTest { 
    @Test 
    public void doSomething() { 
     int x = 5; 

     Assert.assertEquals(x, 5); 
    } 
} 

build.xml

<project name="" basedir=".."> 
    <!-- Main classpath. --> 
    <path id="main.class.path"> 
     <fileset dir="bin/main"/> 
    </path> 

    <!-- Test classpath. --> 
    <path id="test.class.path"> 
     <fileset dir="bin/test"/> 
    </path> 

    <!-- JUnit classpath. --> 
    <path id="junit.class.path"> 
     <fileset dir="lib/main" includes="*.jar"/> 
     <fileset dir="lib/test" includes="*.jar"/> 
     <path refid="main.class.path"/> 
     <path refid="test.class.path"/> 
    </path> 

    <!-- 
     All previous targets omitted for brevity (such as for compiling, etc.), but 
    I assure you all that they work and compile FakeObject.java/FakeObjectUnitTest.java into 
    FakeObject.class/FakeObjectUnitTest.class respectively, and place them in the correct 
bin directories. 
    --> 

    <target name="run-junit" depends="compile"> 

     <property name="junit.path" refid="junit.class.path"/> 
     <echo message="JUnit ClassPath is: ${junit.path}"/> 

     <junit printsummary="yes" haltonerror="yes" haltonfailure="yes"> 
      <classpath refid="junit.class.path"/> 

      <formatter type="xml"/> 

      <batchtest todir="gen/reports"> 
       <fileset dir="src/test/java"> 
        <include name="**/*UnitTest*.java"/> 
       </fileset> 
      </batchtest> 
     </junit> 
    </target> 
</project> 

当我运行在命令行这一目标:

run-junit: 
    [echo] Conducting unit tests with JUnit. 
    [echo] JUnit ClassPath is: /<path-to-my-project>/MyProject/lib/test/hamcrest-1.1.jar:/<path-to-my-project>/MyProject/lib/test/junit-4.10.jar:/<path-to-my-project>/MyProject/bin/main/com/myproject/client/FakeObject.class:/<path-to-my-project>/MyProject/bin/test/com/myproject/client/FakeObjectUnitTest.class 
    [junit] Running com.myproject.client.FakeObjectUnitTest 
    [junit] Tests run: 1, Failures: 0, Errors: 1, Time elapsed: 0 sec 

我这样做到证明它在JUnit类路径上看到FakeObjectUnitTest.class。但是,它会因错误而失败。当我进入了XML测试报告为这个测试,我看到以下内容:

<error message="com.myproject.client.FakeObjectUnitTest" type="java.lang.ClassNotFoundException">java.lang.ClassNotFoundException: com.myproject.client.FakeObjectUnitTest 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:247) 
</error> 

当我详细模式运行Ant(-v)唯一提示我看到的是警告的线沿线的一堆:

忽略异常java.util.zip.ZipException:错误打开zip文件的阅读资源X

...其中x是一个类文件的名称。

我发现this关于SO的问题,问题原来是作者将类文件添加到类路径中,而不是JAR(这使得JUnit不高兴)。所以我尝试从junit.class/path中删除main.class.pathtest.class.path,然后我得到一个异常,没有任何类文件可以找到。

对发生了什么有任何想法或想法?在此先感谢,并对此处的-v问题感到抱歉,但我认为更详细,更好。

回答

5

您需要使用的包状结构:
From the manual

无论路径样值需要要指定,可以使用嵌套元素。这需要的一般形式:

<classpath> 
     <pathelement path="${classpath}"/> 
     <pathelement location="lib/helper.jar"/> 
    </classpath> 

所以,你的解决办法是这样的:在运行JUnit的目标

<!-- JUnit classpath. --> 
<path id="junit.class.path"> 
    <fileset dir="lib/main" includes="*.jar"/> 
    <fileset dir="lib/test" includes="*.jar"/> 
    <pathelement location="bin/main"/> 
    <pathelement location="bin/test"/> 
</path> 
+0

,你是男人。谢谢! – IAmYourFaja

2

看你的类路径:

...:/<path-to-my-project>/MyProject/bin/main/com/myproject/client/FakeObject.class:... 

你不能把个人类这样的类路径。相反,把那在你的包层次的classpath中库的目录:

...:/<path-to-my-project>/MyProject/bin/main:... 
+0

感谢@Jesper( +1) - 但如果您注意到,FakeObject.class在JUnit类路径中的唯一原因是它恰好是正在编译的唯一二进制文件。它在类路径中,因为它在'bin/main'中,它是'main.class.path'的一部分,而'main.class.path'又是'junit.class.path'的一部分,所以除非我错过了' bin/main'已经是JUnit类路径的一部分。平时每个人都是 – IAmYourFaja

0

进行修改如下,

  <batchtest todir="gen/reports"> 
      <fileset dir="bin/tests"> 
       <include name="**/*UnitTest*.class"/> 
      </fileset> 
     </batchtest> 
相关问题