本文介绍了在 Ant、Ivy 和 JUnit 中找不到类 - build.xml 中的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Ant、Ivy 和 JUnit 进行一个简单的(?)测试项目.基本思路是,Ivy 会下载 junit.jar,然后 Ant 会使用它.

请注意,junit jar 在类路径上 因为否则(在 junit 任务中没有 classpath 元素)我会看到 如果不在 Ant 自己的类路径中,则必须包含 junit.jar".此外,下面给出的类 (junit.framework.TestListener) 在 junit-4.8.2.jar 中.

但是,当我在以下内容上尝试 ant test 时,我看到:

测试:构建失败/home/andrew/project/guice/hg/build.xml:33: java.lang.NoClassDefFoundError: junit/framework/TestListener在 java.lang.ClassLoader.defineClass1(Native Method)在 java.lang.ClassLoader.defineClass(ClassLoader.java:791)...在 org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)在 org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)引起:java.lang.ClassNotFoundException:junit.framework.TestListener在 java.net.URLClassLoader$1.run(URLClassLoader.java:366)在 java.net.URLClassLoader$1.run(URLClassLoader.java:355)...

所以我猜我的 build.xml 有问题?什么?

这是build.xml:

<说明>简单示例构建文件</描述><property name="src" location="src"/><property name="build" location="build"/><property name="dist" location="dist"/><property name="lib" location="lib"/><path id="lib.path"><fileset dir="${lib}"/></路径><目标名称=初始化"><tstamp/><mkdir dir="${build}"/></目标><目标名称=编译"依赖=初始化,解析"description="编译源代码"><javac srcdir="${src}" destdir="${build}" classpathref="lib.path"includeantruntime="false"><compilerarg value="-Xlint"/></javac></目标><目标名称=测试"依赖=编译"描述=运行测试"><junit><classpath refid="lib.path"/><批量测试><fileset dir="${build}"><include name="**/*Test.class"/></文件集></batchtest></junit></目标><目标名称=dist"依赖=编译"description="生成分布"><mkdir dir="${dist}/lib"/><jar jarfile="${dist}/lib/example-${DSTAMP}.jar" basedir="${build}"/></目标><目标名称=干净"描述=清理"><delete dir="${build}"/><delete dir="${dist}"/></目标><目标名称=解决"description="下载所需的依赖项"><ivy:检索/></目标></项目>

以及编译后的现有目录结构:

.├──构建│ └── com│ └── isti│ └── 例子│ ├── AppendToList.class│ ├── DumpToStdout.class│ ├── LimitedCounter.class│ ├── MessageSink.class│ ├── MessageSource.class│ └── SinkToSourceTest.class├── build.xml├──区│ └── lib│ └── example-20130412.jar├── ivy.xml├── 库│ ├── junit-4.8.2.jar│ ├── junit-4.8.2-javadoc.jar│ └── junit-4.8.2-sources.jar├── README.md└── src├── 主要│ └── java│ └── com│ └── isti│ └── 例子│ ├── AppendToList.java│ ├── DumpToStdout.java│ ├── LimitedCounter.java│ ├── MessageSink.java│ └── MessageSource.java└── 测试└── 爪哇└── com└── 伊斯蒂└── 例子└── SinkToSourceTest.java

更新 顺便说一下,ant -lib lib test(明确给出 lib 目录)有效.并且在随机网络搜索结果中对此处理的处理有很多令人困惑的描述 - 但我的印象是上述方法与 最新文档(我使用的是 ant 1.9) - 见第 5 点.所以我想这可能是一个 错误错误.

解决方案

示例

项目包含以下文件:

├── build.xml├── ivy.xml└── src├── 主要│ ├── java│ │ └── 组织│ │ └── 演示│ │ └── App.java│ └── 资源│ └── log4j.properties└── 测试└── 爪哇└── 组织└── 演示└── AppTest.java

构建运行如下:

$ ant构建文件:/home/mark/Files/Dev/ivy/demo/build.xml解决:[ivy:resolve] :: Apache Ivy 2.3.0 - 20130110142753 :: http://ant.apache.org/ivy/::[ivy:resolve] :: 加载设置 :: url = jar:file:/home/mark/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml[ivy:resolve] :: 解析依赖项 :: com.myspotontheweb#demo;working@mark-Lemur-Ultra[ivy:resolve] confs: [编译、运行时、测试][ivy:resolve] 找到 org.slf4j#slf4j-api;1.7.5 在公共[ivy:resolve] 在公共场合找到 org.slf4j#slf4j-log4j12;1.7.5[ivy:resolve] 公开发现 log4j#log4j;1.2.17[ivy:resolve] 发现 junit#junit;4.11 公开[ivy:resolve] 发现 org.hamcrest#hamcrest-core;1.3 在公共场合[ivy:resolve] :: 解析报告 :: 解析 347ms :: artifacts dl 14ms---------------------------------------------------------------------||模块 ||文物||配置 |数量|搜索|dwnlded|驱逐||数量|减少|---------------------------------------------------------------------|编译|1 |0 |0 |0 ||1 |0 ||运行时间 |3 |0 |0 |0 ||3 |0 ||测试 |5 |0 |0 |0 ||5 |0 |---------------------------------------------------------------------[ivy:report] 处理/home/mark/.ivy2/cache/com.myspotontheweb-demo-compile.xml 到/home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-compile.html[ivy:report] 处理/home/mark/.ivy2/cache/com.myspotontheweb-demo-runtime.xml 到/home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-runtime.html[ivy:report] 处理/home/mark/.ivy2/cache/com.myspotontheweb-demo-test.xml 到/home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-test.html资源:[复制] 将 1 个文件复制到/home/mark/Files/Dev/ivy/demo/build/classes编译:[javac] 编译 1 个源文件到/home/mark/Files/Dev/ivy/demo/build/classes编译测试:[mkdir] 创建的目录:/home/mark/Files/Dev/ivy/demo/build/test-classes[javac] 编译 1 个源文件到/home/mark/Files/Dev/ivy/demo/build/test-classes测试:[mkdir] 创建的目录:/home/mark/Files/Dev/ivy/demo/build/test-reports[junit] 运行 org.demo.AppTest[junit] 测试运行:1,失败:0,错误:0,经过的时间:0.085 秒建造:[ivy:retrieve] :: 检索 :: com.myspotontheweb#demo[ivy:retrieve] confs: [runtime][ivy:retrieve] 复制了 3 个工件,已经检索了 0 个 (512kB/16ms)[jar] 构建jar:/home/mark/Files/Dev/ivy/demo/build/dist/demo.jar建造成功总时间:4秒

ivy.xml

ivy 的一个非常强大的功能是配置.这些允许您将依赖项组合在一起.

<信息组织=com.myspotontheweb"模块=演示"/><配置><conf name="compile" description="需要编译应用程序"/><conf name="runtime" description="额外的运行时依赖项" extends="compile"/><conf name="test" description="仅用于测试需要" extends="runtime"/></配置><依赖项><!-- 编译依赖项--><dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/><!-- 运行时依赖--><dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/><!-- 测试依赖项--><dependency org="junit" name="junit" rev="4.11" conf="test->default"/></依赖项></ivy-module>

注意事项:

  • 配置使用扩展"功能来模拟 Maven 的编译"、运行时"和测试"Maven 范围.
  • 注意每个依赖项的特殊conf"属性.这是从本地到远程的映射.有关常春藤如何管理远程 Maven 模块的更多详细信息,请参阅:如何通过 ivy 将 Maven 范围映射到 ivy 配置

build.xml

Ivy 配置可以被 cachepath(创建 ANT 路径)和 检索(将文件复制到您的构建中).我还建议使用 report 目标,以便您可以看到每个配置中出现了哪些jar包(对管理传递依赖很有用)

<!--================构建属性================--><property name="src.dir" location="src/main/java"/><property name="resources.dir" location="src/main/resources"/><property name="test.src.dir" location="src/test/java"/><property name="build.dir" location="build"/><property name="classes.dir" location="${build.dir}/classes"/><property name="test.classes.dir" location="${build.dir}/test-classes"/><property name="ivy.reports.dir" location="${build.dir}/ivy-reports"/><property name="test.reports.dir" location="${build.dir}/test-reports"/><property name="dist.dir" location="${build.dir}/dist"/><property name="jar.main.class" value="org.demo.App"/><property name="jar.file" value="${dist.dir}/${ant.project.name}.jar"/><available classname="org.apache.ivy.Main" property="ivy.installed"/><!--============构建设置============--><target name="install-ivy" description="Install ivy"除非="ivy.installed"><mkdir dir="${user.home}/.ant/lib"/><get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/><fail message="Ivy 已安装.再次运行构建"/></目标><target name="resolve" depends="install-ivy" description="使用 ivy 解析类路径"><ivy:resolve/><ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/><ivy:cachepath pathid="compile.path" conf="compile"/><ivy:cachepath pathid="test.path" conf="test"/></目标><!--================编译目标================--><target name="resources" description="将资源复制到类路径中"><copy todir="${classes.dir}"><fileset dir="${resources.dir}"/></复制></目标><目标名称=编译"依赖=解析,资源"描述=编译代码"><mkdir dir="${classes.dir}"/><javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" debug="true" classpathref="compile.path"/></目标><目标名称=编译测试"依赖=编译"描述=编译测试"><mkdir dir="${test.classes.dir}"/><javac srcdir="${test.src.dir}" destdir="${test.classes.dir}" includeantruntime="false" debug="true"><path refid="test.path"/><pathelement path="${classes.dir}"/></classpath></javac></目标><!--============测试目标============--><target name="test" depends="compile-tests" description="运行单元测试"><mkdir dir="${test.reports.dir}"/><junit printsummary="yes"haltonfailure="yes"><path refid="test.path"/><pathelement path="${classes.dir}"/><pathelement path="${test.classes.dir}"/></classpath><formatter type="xml"/><batchtest fork="yes" todir="${test.reports.dir}"><fileset dir="${test.src.dir}"><include name="**/*Test*.java"/><exclude name="**/AllTests.java"/></文件集></batchtest></junit></目标><!--======================构建和运行目标======================--><target name="build" depends="test" description="创建可执行的jar包"><ivy:retrieve pattern="${dist.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" conf="runtime"/><manifestclasspath property="jar.classpath" jarfile="${jar.file}"><fileset dir="${dist.dir}/lib" includes="*.jar"/></classpath></manifestclasspath><jar destfile="${jar.file}" basedir="${classes.dir}"><清单><attribute name="Main-Class" value="${jar.main.class}"/><attribute name="Class-Path" value="${jar.classpath}"/></清单></目标><目标名称=运行"依赖=构建"描述=运行代码"><java jar="${jar.file}" fork="true"/></目标><!--==============清洁目标==============--><target name="clean" description="清理构建文件"><delete dir="${build.dir}"/></目标><target name="clean-all" depends="clean" description="另外清除常春藤缓存"><ivy:cleancache/></目标></项目>

注意:

  • 有条件的install-ivy"目标会自动安装ivy.只需重新运行构建,只需执行一次.

App.java

Hello world 日志示例.

package org.demo;导入 org.slf4j.Logger;导入 org.slf4j.LoggerFactory;/*** 你好,世界!**/公共类应用{静态最终记录器日志 = LoggerFactory.getLogger(App.class);公共静态无效主(字符串[] args){App a = new App();a.speak("你好世界");}公共无效说话(字符串消息){日志信息(消息);}}

AppTest.java

这是我档案中的一个老例子.不使用 Junit 断言.

ackage org.demo;导入 junit.framework.Test;导入 junit.framework.TestCase;导入 junit.framework.TestSuite;/*** 简单应用的单元测试.*/公共类 AppTest扩展测试用例{/*** 创建测试用例** @param testName 测试用例名称*/公共 AppTest( 字符串 testName ){超级(测试名称);}/*** @return 正在测试的测试套件*/公共静态测试套件(){返回新的测试套件( AppTest.class );}/*** 严格的测试 :-)*/公共无效 testApp(){断言真(真);}}

log4j.properties

# 将根记录器级别设置为 DEBUG,并将其唯一的 appender 设置为 A1.log4j.rootLogger=调试,A1# A1 设置为 ConsoleAppender.log4j.appender.A1=org.apache.log4j.ConsoleAppender# A1 使用 PatternLayout.log4j.appender.A1.layout=org.apache.log4j.PatternLayoutlog4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

I am trying to get a simple(?) test project working with Ant, Ivy and JUnit. The basic idea is that Ivy will download junit.jar and then Ant will use it.

Note that the junit jar is on the classpath because otherwise (without the classpath element in the junit task) I see "The <classpath> for <junit> must include junit.jar if not in Ant's own classpath". Also, the class given below (junit.framework.TestListener) is in junit-4.8.2.jar.

However, when I try ant test on the following I see:

test:

BUILD FAILED
/home/andrew/project/guice/hg/build.xml:33: java.lang.NoClassDefFoundError: junit/framework/TestListener
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
...
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
Caused by: java.lang.ClassNotFoundException: junit.framework.TestListener
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
...

So I guess something is wrong with my build.xml? What?

Here is the build.xml:

<project xmlns:ivy="antlib:org.apache.ivy.ant"
         name="java-example" default="dist" basedir=".">

  <description>
    simple example build file
  </description>

  <property name="src" location="src"/>
  <property name="build" location="build"/>
  <property name="dist" location="dist"/>
  <property name="lib" location="lib"/>

  <path id="lib.path">
    <fileset dir="${lib}"/>
  </path>

  <target name="init">
    <tstamp/>
    <mkdir dir="${build}"/>
  </target>

  <target name="compile" depends="init,resolve"
          description="compile the source">
    <javac srcdir="${src}" destdir="${build}" classpathref="lib.path"
           includeantruntime="false">
      <compilerarg value="-Xlint"/>
    </javac>
  </target>

  <target name="test" depends="compile"
          description="run the tests">
    <junit>
      <classpath refid="lib.path"/>
      <batchtest>
        <fileset dir="${build}">
          <include name="**/*Test.class"/>
        </fileset>
      </batchtest>
    </junit>
  </target>

  <target name="dist" depends="compile"
          description="generate the distribution">
    <mkdir dir="${dist}/lib"/>
    <jar jarfile="${dist}/lib/example-${DSTAMP}.jar" basedir="${build}"/>
  </target>

  <target name="clean"
          description="clean up">
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>

  <target name="resolve"
          description="download required dependencies">
    <ivy:retrieve/>
  </target>

</project>

and the existing directory structure after compilation:

.
├── build
│   └── com
│       └── isti
│           └── example
│               ├── AppendToList.class
│               ├── DumpToStdout.class
│               ├── LimitedCounter.class
│               ├── MessageSink.class
│               ├── MessageSource.class
│               └── SinkToSourceTest.class
├── build.xml
├── dist
│   └── lib
│       └── example-20130412.jar
├── ivy.xml
├── lib
│   ├── junit-4.8.2.jar
│   ├── junit-4.8.2-javadoc.jar
│   └── junit-4.8.2-sources.jar
├── README.md
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── isti
    │               └── example
    │                   ├── AppendToList.java
    │                   ├── DumpToStdout.java
    │                   ├── LimitedCounter.java
    │                   ├── MessageSink.java
    │                   └── MessageSource.java
    └── test
        └── java
            └── com
                └── isti
                    └── example
                        └── SinkToSourceTest.java

Update Incidentally, ant -lib lib test (explicitly giving the lib directory) works. And there are lots of confused descriptions of the handling of this in random web search results - but my impression is that the approach above is consistent with the latest docs (I am using ant 1.9) - see point 5. So I am thinking this may be a bug; bug.

解决方案

Example

Project contains the following files:

├── build.xml
├── ivy.xml
└── src
    ├── main
    │   ├── java
    │   │   └── org
    │   │       └── demo
    │   │           └── App.java
    │   └── resources
    │       └── log4j.properties
    └── test
        └── java
            └── org
                └── demo
                    └── AppTest.java

Build runs as follows:

$ ant
Buildfile: /home/mark/Files/Dev/ivy/demo/build.xml

resolve:
[ivy:resolve] :: Apache Ivy 2.3.0 - 20130110142753 :: http://ant.apache.org/ivy/ ::
[ivy:resolve] :: loading settings :: url = jar:file:/home/mark/.ant/lib/ivy.jar!/org/apache/ivy/core/settings/ivysettings.xml
[ivy:resolve] :: resolving dependencies :: com.myspotontheweb#demo;working@mark-Lemur-Ultra
[ivy:resolve]   confs: [compile, runtime, test]
[ivy:resolve]   found org.slf4j#slf4j-api;1.7.5 in public
[ivy:resolve]   found org.slf4j#slf4j-log4j12;1.7.5 in public
[ivy:resolve]   found log4j#log4j;1.2.17 in public
[ivy:resolve]   found junit#junit;4.11 in public
[ivy:resolve]   found org.hamcrest#hamcrest-core;1.3 in public
[ivy:resolve] :: resolution report :: resolve 347ms :: artifacts dl 14ms
    ---------------------------------------------------------------------
    |                  |            modules            ||   artifacts   |
    |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
    ---------------------------------------------------------------------
    |      compile     |   1   |   0   |   0   |   0   ||   1   |   0   |
    |      runtime     |   3   |   0   |   0   |   0   ||   3   |   0   |
    |       test       |   5   |   0   |   0   |   0   ||   5   |   0   |
    ---------------------------------------------------------------------
[ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-compile.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-compile.html
[ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-runtime.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-runtime.html
[ivy:report] Processing /home/mark/.ivy2/cache/com.myspotontheweb-demo-test.xml to /home/mark/Files/Dev/ivy/demo/build/ivy-reports/com.myspotontheweb-demo-test.html

resources:
     [copy] Copying 1 file to /home/mark/Files/Dev/ivy/demo/build/classes

compile:
    [javac] Compiling 1 source file to /home/mark/Files/Dev/ivy/demo/build/classes

compile-tests:
    [mkdir] Created dir: /home/mark/Files/Dev/ivy/demo/build/test-classes
    [javac] Compiling 1 source file to /home/mark/Files/Dev/ivy/demo/build/test-classes

test:
    [mkdir] Created dir: /home/mark/Files/Dev/ivy/demo/build/test-reports
    [junit] Running org.demo.AppTest
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.085 sec

build:
[ivy:retrieve] :: retrieving :: com.myspotontheweb#demo
[ivy:retrieve]  confs: [runtime]
[ivy:retrieve]  3 artifacts copied, 0 already retrieved (512kB/16ms)
      [jar] Building jar: /home/mark/Files/Dev/ivy/demo/build/dist/demo.jar

BUILD SUCCESSFUL
Total time: 4 seconds

ivy.xml

A very powerful feature of ivy is configurations. These allow you to group dependencies together.

<ivy-module version="2.0">
    <info organisation="com.myspotontheweb" module="demo"/>

    <configurations>
        <conf name="compile" description="Required to compile application"/>
        <conf name="runtime" description="Additional run-time dependencies" extends="compile"/>
        <conf name="test"    description="Required for test only" extends="runtime"/>
    </configurations>

    <dependencies>
        <!-- compile dependencies -->
        <dependency org="org.slf4j" name="slf4j-api" rev="1.7.5" conf="compile->default"/>

        <!-- runtime dependencies -->
        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.5" conf="runtime->default"/>

        <!-- test dependencies -->
        <dependency org="junit" name="junit" rev="4.11" conf="test->default"/>
    </dependencies>

</ivy-module>

Notes:

  • The configurations use the "extends" feature in order to emulate the Maven "compile", "runtime" and "test" Maven scopes.
  • Note the special "conf" attribute on each dependency. This is the mapping from local to remote. For more details on how remote Maven modules are managed by ivy see: How are maven scopes mapped to ivy configurations by ivy

build.xml

Ivy configurations can be leveraged by tasks like cachepath (to create an ANT path) and retrieve (copy files into your build).I also recommend using the report target so that you can see which jars appear in each configuration (Useful to managing transitive dependencies)

<project name="demo" default="build" xmlns:ivy="antlib:org.apache.ivy.ant">

    <!--
    ================
    Build properties
    ================
    -->
    <property name="src.dir"          location="src/main/java"/>
    <property name="resources.dir"    location="src/main/resources"/>
    <property name="test.src.dir"     location="src/test/java"/>
    <property name="build.dir"        location="build"/>
    <property name="classes.dir"      location="${build.dir}/classes"/>
    <property name="test.classes.dir" location="${build.dir}/test-classes"/>
    <property name="ivy.reports.dir"  location="${build.dir}/ivy-reports"/>
    <property name="test.reports.dir" location="${build.dir}/test-reports"/>
    <property name="dist.dir"         location="${build.dir}/dist"/>

    <property name="jar.main.class" value="org.demo.App"/>
    <property name="jar.file"       value="${dist.dir}/${ant.project.name}.jar"/>

    <available classname="org.apache.ivy.Main" property="ivy.installed"/>

    <!--
    ===========
    Build setup
    ===========
    -->
    <target name="install-ivy" description="Install ivy" unless="ivy.installed">
        <mkdir dir="${user.home}/.ant/lib"/>
        <get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
        <fail message="Ivy has been installed. Run the build again"/>
    </target>

    <target name="resolve" depends="install-ivy" description="Use ivy to resolve classpaths">
        <ivy:resolve/>

        <ivy:report todir='${ivy.reports.dir}' graph='false' xml='false'/>

        <ivy:cachepath pathid="compile.path" conf="compile"/>
        <ivy:cachepath pathid="test.path"    conf="test"/>
    </target>

    <!--
    ===============
    Compile targets
    ===============
    -->
    <target name="resources" description="Copy resources into classpath">
        <copy todir="${classes.dir}">
            <fileset dir="${resources.dir}"/>
        </copy>
    </target>

    <target name="compile" depends="resolve,resources" description="Compile code">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" includeantruntime="false" debug="true" classpathref="compile.path"/>
    </target>

    <target name="compile-tests" depends="compile" description="Compile tests">
        <mkdir dir="${test.classes.dir}"/>
        <javac srcdir="${test.src.dir}" destdir="${test.classes.dir}" includeantruntime="false" debug="true">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${classes.dir}"/>
            </classpath>
        </javac>
    </target>

    <!--
    ============
    Test targets
    ============
    -->
    <target name="test" depends="compile-tests" description="Run unit tests">
        <mkdir dir="${test.reports.dir}"/>
        <junit printsummary="yes" haltonfailure="yes">
            <classpath>
                <path refid="test.path"/>
                <pathelement path="${classes.dir}"/>
                <pathelement path="${test.classes.dir}"/>
            </classpath>
            <formatter type="xml"/>
            <batchtest fork="yes" todir="${test.reports.dir}">
                <fileset dir="${test.src.dir}">
                    <include name="**/*Test*.java"/>
                    <exclude name="**/AllTests.java"/>
                </fileset>
            </batchtest>
        </junit>
    </target>

    <!--
    =====================
    Build and run targets
    =====================
    -->
    <target name="build" depends="test" description="Create executable jar archive">
        <ivy:retrieve pattern="${dist.dir}/lib/[artifact]-[revision](-[classifier]).[ext]" conf="runtime"/>

        <manifestclasspath property="jar.classpath" jarfile="${jar.file}">
            <classpath>
                <fileset dir="${dist.dir}/lib" includes="*.jar"/>
            </classpath>
        </manifestclasspath>

        <jar destfile="${jar.file}" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${jar.main.class}" />
                <attribute name="Class-Path" value="${jar.classpath}" />
            </manifest>
        </jar>
    </target>

    <target name="run" depends="build" description="Run code">
        <java jar="${jar.file}" fork="true"/>
    </target>

    <!--
    =============
    Clean targets
    =============
    -->
    <target name="clean" description="Cleanup build files">
        <delete dir="${build.dir}"/>
    </target>

    <target name="clean-all" depends="clean" description="Additionally purge ivy cache">
        <ivy:cleancache/>
    </target>

</project>

Note:

  • The conditional "install-ivy" target will install ivy automatically. Just re-run the build, only needs to be done once.

App.java

Hello world logging example.

package org.demo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Hello world!
 *
 */
public class App {
    static final Logger log = LoggerFactory.getLogger(App.class);

    public static void main( String[] args ) {
        App a = new App();
        a.speak("hello world");
    }

    public void speak(String message) {
        log.info(message);
    }
}

AppTest.java

This is an old example from my archives. Not using the Junit assertions.

ackage org.demo;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest
    extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp()
    {
        assertTrue( true );
    }
}

log4j.properties

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1

# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender

# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

这篇关于在 Ant、Ivy 和 JUnit 中找不到类 - build.xml 中的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 14:02