4

我正在尝试遵循 apache 的 ANT 教程:

http://ant.apache.org/manual/index.html

我目前在 JUnit 部分,但我不断收到与无法找到 junit.framework 包相关的错误。

我相信我已经完全按照以下教程进行操作 - 以下是详细信息:

-----我的文件结构-----

build.xml
/build
../classes
/lib
..log4j-1.2.8.jar
myManifest
/src
..HelloWorldTest.java
..log4j.properties
../oata
....HelloWorld.java

------来源-----

我的清单:

Main-Class: oata.HelloWorld

构建.xml:

<project name ="HelloWorld" basedir="." default="main">
    <property name="src.dir" value="src" />
    <property name="build.dir" value="build" />
    <property name="classes.dir" value="${build.dir}/classes" />
    <property name="jar.dir"    value="${build.dir}/jar" />
    <property name="lib.dir"    value="lib" />

    <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar" />
    </path>

    <property name="main-class" value="oata.HelloWorld" />

    <target name="clean">
        <delete dir="${build.dir}"/>
    </target>

    <target name="compile">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" />
        <copy todir="${classes.dir}" >
            <fileset dir="${src.dir}" excludes="**/*.java" />
        </copy>
    </target>

    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}" />
        <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}" />
            </manifest>
        </jar>
    </target>

    <target name="run" depends="jar">
        <java fork="true" classname="${main-class}">
            <classpath>
                <path refid="classpath"/>
            <path id="application" location="${jar.dir}/${ant.project.name}.jar"/>
            </classpath>
        </java>
    </target>

    <target name="junit" depends="jar">
            <junit printsummary="yes">
                <classpath>
                    <path refid="classpath"/>
                    <path refid="application"/>
                </classpath>

                <batchtest fork="yes">
                    <fileset dir="${src.dir}" includes="*Test.java"/>
                </batchtest>
            </junit>
        </target>

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

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

HelloWorldTest.java:

public class HelloWorldTest extends junit.framework.TestCase {

    public void testNothing() {
    }

    public void testWillAlwaysFail() {
        fail("An error message");
    }

}

HelloWorld.java

package oata;

import org.apache.log4j.Logger;

public class HelloWorld {
    static Logger logger = Logger.getLogger(HelloWorld.class);

    public static void main(String [] args){
        logger.info("Hello World!");
    }
}

log4j.properties:

log4j.rootLogger=DEBUG, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%m%n

- -输出 - -

 ant -verbose junit
Apache Ant(TM) version 1.8.2 compiled on June 20 2012
Trying the default build file: build.xml
Buildfile: /Users/jtyler/Projects/AntHelloWorld/build.xml
Detected Java version: 1.6 in: /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Detected OS: Mac OS X
parsing buildfile /Users/jtyler/Projects/AntHelloWorld/build.xml with URI = file:/Users/jtyler/Projects/AntHelloWorld/build.xml
Project base dir set to: /Users/jtyler/Projects/AntHelloWorld
parsing buildfile jar:file:/usr/share/ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml with URI = jar:file:/usr/share/ant/lib/ant.jar!/org/apache/tools/ant/antlib.xml from a zip file
Build sequence for target(s) `junit' is [compile, jar, junit]
Complete build sequence is [compile, jar, junit, clean, run, main, clean-build, ]

compile:
    [mkdir] Skipping /Users/jtyler/Projects/AntHelloWorld/build/classes because it already exists.
    [javac] /Users/jtyler/Projects/AntHelloWorld/build.xml:20: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] HelloWorldTest.java added as HelloWorldTest.class doesn't exist.
    [javac] /Users/jtyler/Projects/AntHelloWorld/src/log4j.properties skipped - don't know how to handle it
    [javac] oata/HelloWorld.java added as oata/HelloWorld.class doesn't exist.
    [javac] Compiling 2 source files to /Users/jtyler/Projects/AntHelloWorld/build/classes
    [javac] Using modern compiler
    [javac] Compilation arguments:
    [javac] '-d'
    [javac] '/Users/jtyler/Projects/AntHelloWorld/build/classes'
    [javac] '-classpath'
    [javac] '/Users/jtyler/Projects/AntHelloWorld/build/classes:/Users/jtyler/Projects/AntHelloWorld/lib/log4j-1.2.8.jar:/usr/share/ant/lib/ant-launcher.jar:/usr/share/ant/lib/ant-antlr.jar:/usr/share/ant/lib/ant-jmf.jar:/usr/share/ant/lib/ant-junit.jar:/usr/share/ant/lib/ant-junit4.jar:/usr/share/ant/lib/ant-swing.jar:/usr/share/ant/lib/ant-testutil.jar:/usr/share/ant/lib/ant.jar'
    [javac] '-sourcepath'
    [javac] '/Users/jtyler/Projects/AntHelloWorld/src'
    [javac] '-g:none'
    [javac] 
    [javac] The ' characters around the executable and arguments are
    [javac] not part of the command.
    [javac] Files to be compiled:
    [javac]     /Users/jtyler/Projects/AntHelloWorld/src/HelloWorldTest.java
    [javac]     /Users/jtyler/Projects/AntHelloWorld/src/oata/HelloWorld.java
    [javac] /Users/jtyler/Projects/AntHelloWorld/src/HelloWorldTest.java:1: package junit.framework does not exist
    [javac] public class HelloWorldTest extends junit.framework.TestCase {
    [javac]                                                    ^
    [javac] /Users/jtyler/Projects/AntHelloWorld/src/HelloWorldTest.java:7: cannot find symbol
    [javac] symbol  : method fail(java.lang.String)
    [javac] location: class HelloWorldTest
    [javac]         fail("An error message");
    [javac]         ^
    [javac] 2 errors

BUILD FAILED
/Users/jtyler/Projects/AntHelloWorld/build.xml:20: Compile failed; see the compiler error output for details.
    at org.apache.tools.ant.taskdefs.Javac.compile(Javac.java:1150)
    at org.apache.tools.ant.taskdefs.Javac.execute(Javac.java:912)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:390)
    at org.apache.tools.ant.Target.performTasks(Target.java:411)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
    at org.apache.tools.ant.Main.runBuild(Main.java:809)
    at org.apache.tools.ant.Main.startAnt(Main.java:217)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)

Total time: 0 seconds

是否有一些我遗漏的东西需要包含在教程中(或未提及)?

编辑:根据亚历克斯的询问,我测试了我的共享目录中是否有 ant 的 junit jars(我这样做了):

$ ls /usr/share/ant/lib/ant-junit*.jar
/usr/share/ant/lib/ant-junit.jar    /usr/share/ant/lib/ant-junit4.jar

我还尝试手动将 ant-junit、ant-junit4.jar 和 junit.jar 放入我的项目的 lib 目录中,运行ant clean junit后出现以下结果(所有错误) :

  • junit.jar - /Users/jtyler/Projects/AntHelloWorld/build.xml:45:未找到参考应用程序。
  • ant-junit.jar: 包 junit.framework 不存在
  • ant-junit.jar 和 ant.junit4.jar:包 junit.framework 不存在
  • ant-junit4.jar:包junit.framework不存在

编辑lib 文件夹中仅包含 junit.jar 并调用ant clean junit时的整个错误是:

$ ant clean junit
Buildfile: /Users/jtyler/Projects/AntHelloWorld/build.xml

clean:
   [delete] Deleting directory /Users/jtyler/Projects/AntHelloWorld/build

compile:
    [mkdir] Created dir: /Users/jtyler/Projects/AntHelloWorld/build/classes
    [javac] /Users/jtyler/Projects/AntHelloWorld/build.xml:20: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 2 source files to /Users/jtyler/Projects/AntHelloWorld/build/classes
     [copy] Copying 1 file to /Users/jtyler/Projects/AntHelloWorld/build/classes

jar:
    [mkdir] Created dir: /Users/jtyler/Projects/AntHelloWorld/build/jar
      [jar] Building jar: /Users/jtyler/Projects/AntHelloWorld/build/jar/HelloWorld.jar

junit:

BUILD FAILED
/Users/jtyler/Projects/AntHelloWorld/build.xml:45: Reference application not found.
4

3 回答 3

3

该教程具有误导性。ant 中包含的 junit 文件不起作用。我下载了 juinit 并将 jar 文件复制到项目的 lib 文件夹中,现在可以正常工作了。

于 2014-03-19T21:11:05.530 回答
2

除了在我的 lib 目录中包含 junit.jar 文件之外,我还在 junit 任务声明上方的 build.xml 文件中添加了以下行:

<path id="application" location="${jar.dir}/${ant.project.name}.jar"/>

这是“运行”任务定义中“应用程序”路径 ID 声明的副本。

应用程序构建成功,我使用ant junit得到以下输出(预计测试失败):

ant junit
Buildfile: /Users/jtyler/Projects/AntHelloWorld/build.xml

compile:
    [javac] /Users/jtyler/Projects/AntHelloWorld/build.xml:20: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds

jar:

junit:
    [junit] Running HelloWorldTest
    [junit] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 0.001 sec
    [junit] Test HelloWorldTest FAILED

BUILD SUCCESSFUL
Total time: 1 second

评论以下问题将不胜感激:

  1. 我实际上需要在我的 lib 文件夹中包含 junit.jar 文件这一事实是我应该关注的吗?如果 ant 的教程明确指出“因为 Ant 有一个内置的 JUnit 3.8.2,您可以直接开始使用它”,我认为这不是必需的。

  2. 我需要在运行任务定义之外定义“应用程序”路径ID的事实是apache ant教程中的错字吗?或者还有其他我错过或应该考虑的事情吗?

感谢所有帮助过的人。

于 2012-11-07T20:19:14.900 回答
1

您必须在编译和任务的类路径中指定junit.jar自己。<junit>这不会自动包含在您的编译中:

<!--  Contains junit.jar and other needed test classes -->
<path id="junit.classpath">
    <fileset dir="${junit.directory}"/>
</path>

<!-- Contains third party jars your code is dependent upon -->
<path id="main.classpath">
    <fileset dir="${dependent.jar.dir}"/>
</path>

<!-- Your main Java source code directory -->
<property name="main.srcdir" value="${basedir}/src/main/java"/>

<!-- Your main Junit test directory source code -->
<property name="test.srcdir" value="${basedir}/src/test/java"/>

<!-- Where you're compiling your main classes to -->
<property name="main.destdir" value="${basedir}/target/classes"/>

<!-- Where you're compiling your test classes to -->
<property name="test.destdir" value="${basedir}/target/test-classes"/>
[...]

<!-- Compile Test Classes -->
<!-- Notice you have three classpath elements:
    * Your main classes you compiled before
    * Your test main classpath that your main classes
      were dependent up
    * The junit.jar classpath
-->

<javac destdir="${test.destdir}"
      srcdir="${test.srcdir}">
      <classpath>
          <!-- Your non-test classes you compiled before -->
          <pathelement path="${main.destdir}/> 
      </classpath>
      <classpath refid="junit.classpath"/>
      <classpath refid="main.classpath"/>
</javac>


<!-- Now run your unit tests: Note how you have the same
     three classpath elements as before -->

 <junit fork="yes">
     <classpath>
         <pathelement path="${main.destdir}"/>
         <pathelement path="${test.destdir}"/>
     </classpath>
      <classpath refid="main.classpath"/>
      <classpath refid="junit.classpath"/>
      [...]
  </junit>
于 2012-11-07T19:54:58.443 回答