2006-09-11 04:19:00 +00:00
|
|
|
<!--
|
|
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
|
|
this work for additional information regarding copyright ownership.
|
|
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
|
|
(the "License"); you may not use this file except in compliance with
|
|
|
|
the License. You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
-->
|
2005-03-21 18:14:21 +00:00
|
|
|
<html>
|
|
|
|
<head>
|
2010-11-11 17:04:16 +00:00
|
|
|
<title>Tutorial: Hello World with Apache Ant</title>
|
2007-05-02 06:56:16 +00:00
|
|
|
<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
|
2005-03-21 18:14:21 +00:00
|
|
|
</head>
|
|
|
|
<body>
|
2010-11-11 17:04:16 +00:00
|
|
|
<h1>Tutorial: Hello World with Apache Ant</h1>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>This document provides a step by step tutorial for starting Java programming with Apache Ant. It
|
|
|
|
does <strong>not</strong> contain deeper knowledge about Java or Ant. This tutorial has the goal to let you see, how to
|
|
|
|
do the easiest steps in Ant.</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<h2>Content</h2>
|
2018-02-08 22:52:33 +01:00
|
|
|
<ul>
|
2005-03-21 18:14:21 +00:00
|
|
|
<li><a href="#prepare">Preparing the project</a></li>
|
|
|
|
<li><a href="#four-steps">Enhance the build file</a></li>
|
|
|
|
<li><a href="#enhance">Enhance the build file</a></li>
|
|
|
|
<li><a href="#ext-libs">Using external libraries</a></li>
|
2005-06-04 07:34:02 +00:00
|
|
|
<li><a href="#resources">Resources</a></li>
|
2018-02-08 22:52:33 +01:00
|
|
|
</ul>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="prepare">Preparing the project</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>We want to separate the source from the generated files, so our Java source files will be in <samp>src</samp>
|
|
|
|
folder. All generated files should be under <samp>build</samp>, and there split into several subdirectories for the
|
|
|
|
individual steps: <samp>classes</samp> for our compiled files and <samp>jar</samp> for our own JAR-file.</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>We have to create only the <samp>src</samp> directory. (Because I am working on Windows, here is the Windows
|
|
|
|
syntax—translate to your shell):</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<pre class="code">md src</pre>
|
|
|
|
|
|
|
|
<p>The following simple Java class just prints a fixed message out to STDOUT, so just write this code
|
|
|
|
into <samp>src\oata\HelloWorld.java</samp>.</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
package oata;
|
|
|
|
|
|
|
|
public class HelloWorld {
|
|
|
|
public static void main(String[] args) {
|
|
|
|
System.out.println("Hello World");
|
|
|
|
}
|
2018-02-28 07:58:59 +01:00
|
|
|
}</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<p>Now just try to compile and run that:</p>
|
2006-05-31 16:28:20 +00:00
|
|
|
<pre class="code">
|
|
|
|
md build\classes
|
|
|
|
javac -sourcepath src -d build\classes src\oata\HelloWorld.java
|
2018-02-28 07:58:59 +01:00
|
|
|
java -cp build\classes oata.HelloWorld</pre>
|
2006-05-31 16:28:20 +00:00
|
|
|
which will result in
|
2018-02-28 07:58:59 +01:00
|
|
|
<pre class="output">Hello World</pre>
|
2006-05-31 16:28:20 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Creating a jar-file is not very difficult. But creating a <em>startable</em> jar-file needs more steps: create a
|
2006-05-31 16:28:20 +00:00
|
|
|
manifest-file containing the start class, creating the target directory and archiving the files.</p>
|
|
|
|
<pre class="code">
|
2006-07-11 08:38:58 +00:00
|
|
|
echo Main-Class: oata.HelloWorld>myManifest
|
2006-05-31 16:28:20 +00:00
|
|
|
md build\jar
|
2006-07-11 08:38:58 +00:00
|
|
|
jar cfm build\jar\HelloWorld.jar myManifest -C build\classes .
|
2018-02-28 07:58:59 +01:00
|
|
|
java -jar build\jar\HelloWorld.jar</pre>
|
2006-05-31 16:28:20 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p><strong>Note</strong>: Do not have blanks around the >-sign in the <code>echo
|
|
|
|
Main-Class</code> instruction because it would falsify it!</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="four-steps">Four steps to a running application</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>After finishing the java-only step we have to think about our build process. We <em>have</em> to compile our code,
|
|
|
|
otherwise we couldn't start the program. Oh—<q>start</q>—yes, we could provide a target for
|
|
|
|
that. We <em>should</em> package our application. Now it's only one class—but if you want to provide a download,
|
|
|
|
no one would download several hundreds files ... (think about a complex Swing GUI—so let us create a jar file. A
|
|
|
|
startable jar file would be nice ... And it's a good practise to have a <q>clean</q> target, which deletes all the
|
|
|
|
generated stuff. Many failures could be solved just by a "clean build".</p>
|
|
|
|
|
|
|
|
<p>By default Ant uses <samp>build.xml</samp> as the name for a buildfile, so our <samp>.\build.xml</samp> would be:</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
<pre class="code">
|
|
|
|
<project>
|
|
|
|
|
|
|
|
<target name="clean">
|
|
|
|
<delete dir="build"/>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="compile">
|
|
|
|
<mkdir dir="build/classes"/>
|
|
|
|
<javac srcdir="src" destdir="build/classes"/>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="jar">
|
|
|
|
<mkdir dir="build/jar"/>
|
|
|
|
<jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
|
|
|
|
<manifest>
|
|
|
|
<attribute name="Main-Class" value="oata.HelloWorld"/>
|
|
|
|
</manifest>
|
|
|
|
</jar>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="run">
|
|
|
|
<java jar="build/jar/HelloWorld.jar" fork="true"/>
|
|
|
|
</target>
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
</project></pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<p>Now you can compile, package and run the application via</p>
|
|
|
|
<pre class="code">
|
|
|
|
ant compile
|
|
|
|
ant jar
|
2018-02-28 07:58:59 +01:00
|
|
|
ant run</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
<p>Or shorter with</p>
|
2018-02-28 07:58:59 +01:00
|
|
|
<pre class="code">ant compile jar run</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<p>While having a look at the buildfile, we will see some similar steps between Ant and the Java-only commands:</p>
|
2006-05-31 16:28:20 +00:00
|
|
|
<table>
|
|
|
|
<tr>
|
2018-02-28 07:58:59 +01:00
|
|
|
<th>Java-only</th>
|
2006-05-31 16:28:20 +00:00
|
|
|
<th>Ant</th>
|
|
|
|
</tr>
|
|
|
|
<tr>
|
2018-02-28 07:58:59 +01:00
|
|
|
<td><pre class="code">
|
2006-05-31 16:28:20 +00:00
|
|
|
md build\classes
|
2006-07-11 08:38:58 +00:00
|
|
|
javac
|
|
|
|
-sourcepath src
|
|
|
|
-d build\classes
|
2006-05-31 16:28:20 +00:00
|
|
|
src\oata\HelloWorld.java
|
|
|
|
echo Main-Class: oata.HelloWorld>mf
|
|
|
|
md build\jar
|
2006-07-11 08:38:58 +00:00
|
|
|
jar cfm
|
|
|
|
build\jar\HelloWorld.jar
|
|
|
|
mf
|
|
|
|
-C build\classes
|
2006-05-31 16:28:20 +00:00
|
|
|
.
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
java -jar build\jar\HelloWorld.jar</pre></td>
|
|
|
|
<td><pre class="code">
|
2006-05-31 16:28:20 +00:00
|
|
|
<mkdir dir="build/classes"/>
|
2006-07-11 08:38:58 +00:00
|
|
|
<javac
|
|
|
|
srcdir="src"
|
2006-05-31 16:28:20 +00:00
|
|
|
destdir="build/classes"/>
|
2018-02-28 07:58:59 +01:00
|
|
|
<em><!-- automatically detected --></em>
|
|
|
|
<em><!-- obsolete; done via manifest tag --></em>
|
2006-05-31 16:28:20 +00:00
|
|
|
<mkdir dir="build/jar"/>
|
2006-07-11 08:38:58 +00:00
|
|
|
<jar
|
|
|
|
destfile="build/jar/HelloWorld.jar"
|
|
|
|
|
2006-05-31 16:28:20 +00:00
|
|
|
basedir="build/classes">
|
|
|
|
<manifest>
|
|
|
|
<attribute name="Main-Class" value="oata.HelloWorld"/>
|
|
|
|
</manifest>
|
|
|
|
</jar>
|
2018-02-28 07:58:59 +01:00
|
|
|
<java jar="build/jar/HelloWorld.jar" fork="true"/></pre></td>
|
|
|
|
</tr>
|
|
|
|
</table>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="enhance">Enhance the build file</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Now that we have a working buildfile, we could do some enhancements: many time you are referencing the same
|
|
|
|
directories, main-class and jar-name are hard coded, and while invoking you have to remember the right order of build
|
|
|
|
steps.</p>
|
|
|
|
<p>The first and second point would be addressed with <em>properties</em>, the third with a special property—an
|
|
|
|
attribute of the <code><project></code> tag and the fourth problem can be solved using dependencies.</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
<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="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}"/>
|
|
|
|
</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 jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="clean-build" depends="clean,jar"/>
|
|
|
|
|
|
|
|
<target name="main" depends="clean,run"/>
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
</project></pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Now it's easier, just do a <code>ant</code> and you will get</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
<pre class="output">
|
|
|
|
Buildfile: build.xml
|
|
|
|
|
|
|
|
clean:
|
|
|
|
|
|
|
|
compile:
|
|
|
|
[mkdir] Created dir: C:\...\build\classes
|
|
|
|
[javac] Compiling 1 source file to C:\...\build\classes
|
|
|
|
|
|
|
|
jar:
|
|
|
|
[mkdir] Created dir: C:\...\build\jar
|
|
|
|
[jar] Building jar: C:\...\build\jar\HelloWorld.jar
|
|
|
|
|
|
|
|
run:
|
|
|
|
[java] Hello World
|
|
|
|
|
|
|
|
main:
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
BUILD SUCCESSFUL</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="ext-libs">Using external libraries</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Somehow told us not to use sys-statements. For log-statements we should use a Logging API—customizable to a
|
|
|
|
high degree (including switching off during usual life (= not development) execution). We use Log4J for that,
|
|
|
|
because</p>
|
2018-02-08 22:52:33 +01:00
|
|
|
<ul>
|
2005-03-21 18:14:21 +00:00
|
|
|
<li>it is not part of the JDK (1.4+) and we want to show how to use external libs</li>
|
|
|
|
<li>it can run under JDK 1.2 (as Ant)</li>
|
|
|
|
<li>it's highly configurable</li>
|
2006-05-31 16:28:20 +00:00
|
|
|
<li>it's from Apache ;-)</li>
|
2018-02-08 22:52:33 +01:00
|
|
|
</ul>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>We store our external libraries in a new directory <samp>lib</samp>. Log4J can
|
|
|
|
be <a href="https://archive.apache.org/dist/logging/log4j/1.2.17/logging-log4j-1.2.17.zip">downloaded [1]</a> from
|
|
|
|
Logging's Homepage. Create the <samp>lib</samp> directory and extract the <samp>log4j-1.2.17.jar</samp> into that
|
|
|
|
directory. After that we have to modify our Java source file to use that library and our buildfile so that this library
|
|
|
|
could be accessed during compilation and run.</p>
|
|
|
|
<p>Working with Log4J is documented inside its manual. Here we use the <var>MyApp</var>-example from
|
|
|
|
the <a href="https://logging.apache.org/log4j/1.2/manual.html">Short Manual [2]</a>. First we have to modify the java
|
|
|
|
source to use the logging framework:</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
package oata;
|
|
|
|
|
|
|
|
<b>import org.apache.log4j.Logger;</b>
|
|
|
|
<b>import org.apache.log4j.BasicConfigurator;</b>
|
|
|
|
|
|
|
|
public class HelloWorld {
|
|
|
|
<b>static Logger logger = Logger.getLogger(HelloWorld.class);</b>
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
<b>BasicConfigurator.configure();</b>
|
2018-02-28 07:58:59 +01:00
|
|
|
<span style="color:blue"><b>logger.info("Hello World");</b></span> // the old SysO-statement
|
2005-03-21 18:14:21 +00:00
|
|
|
}
|
2018-02-28 07:58:59 +01:00
|
|
|
}</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2005-08-01 15:30:27 +00:00
|
|
|
<p>Most of the modifications are "framework overhead" which has to be done once. The blue line is our "old System-out"
|
2005-03-21 18:14:21 +00:00
|
|
|
statement.</p>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Don't try to run <code>ant</code>—you will only get lot of compiler errors. Log4J is not on the classpath so we
|
|
|
|
have to do a little work here. But do not change the <code>CLASSPATH</code> environment variable! This is only for this
|
|
|
|
project and maybe you would break other environments (this is one of the most famous mistakes when working with Ant). We
|
|
|
|
introduce Log4J (or to be more precise: all libraries (jar-files) which are somewhere under <samp>.\lib</samp>) into our
|
|
|
|
buildfile:</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
<project name="HelloWorld" basedir="." default="main">
|
|
|
|
...
|
|
|
|
<b><property name="lib.dir" value="lib"/></b>
|
|
|
|
|
|
|
|
<b><path id="classpath"></b>
|
|
|
|
<b><fileset dir="${lib.dir}" includes="**/*.jar"/></b>
|
|
|
|
<b></path></b>
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
<target name="compile">
|
|
|
|
<mkdir dir="${classes.dir}"/>
|
|
|
|
<javac srcdir="${src.dir}" destdir="${classes.dir}" <b>classpathref="classpath"</b>/>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
<target name="run" depends="jar">
|
|
|
|
<java fork="true" <b>classname="${main-class}"</b>>
|
|
|
|
<b><classpath></b>
|
|
|
|
<b><path refid="classpath"/></b>
|
2018-02-28 07:58:59 +01:00
|
|
|
<span style="color:red"><b><path location="${jar.dir}/${ant.project.name}.jar"/></b></span>
|
2005-03-21 18:14:21 +00:00
|
|
|
<b></classpath></b>
|
|
|
|
</java>
|
|
|
|
</target>
|
|
|
|
|
|
|
|
...
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
</project></pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide a
|
|
|
|
jarname <em>and</em> a classpath. So add our class in the red line to the already defined path and start as
|
|
|
|
usual. Running <code>ant</code> would give (after the usual compile stuff):</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<pre class="output">[java] 0 [main] INFO oata.HelloWorld - Hello World</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<p>What's that?</p>
|
|
|
|
<ul>
|
2018-02-28 07:58:59 +01:00
|
|
|
<li><code>[java]</code> Ant task running at the moment</li>
|
|
|
|
<li><code>0</code> <small>sorry, don't know—some Log4J stuff</small></li>
|
|
|
|
<li><code>[main]</code> the running thread from our application</li>
|
|
|
|
<li><code>INFO</code> log level of that statement</li>
|
|
|
|
<li><code>oata.HelloWorld</code> source of that statement</li>
|
|
|
|
<li><code>-</code> separator</li>
|
|
|
|
<li><code>Hello World</code> the message</li>
|
2005-03-21 18:14:21 +00:00
|
|
|
</ul>
|
2018-02-08 22:52:33 +01:00
|
|
|
<p>For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="config-files">Configuration files</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Why we have used Log4J? "It's highly configurable"? No—all is hardcoded! But that is not the fault of
|
|
|
|
Log4J—it's ours. We had coded <code>BasicConfigurator.configure();</code> which implies a simple, but hardcoded
|
|
|
|
configuration. More comfortable would be using a property file. In the Java source file, delete
|
|
|
|
the <code>BasicConfiguration</code> line from the <code>main()</code> method (and the
|
|
|
|
related <code>import</code>-statement). Log4J will search then for a configuration as described in it's manual. Then
|
|
|
|
create a new file <samp>src/log4j.properties</samp>. That's the default name for Log4J's configuration and using that
|
|
|
|
name would make life easier—not only the framework knows what is inside, you too!</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
log4j.rootLogger=DEBUG, <b>stdout</b>
|
|
|
|
|
|
|
|
log4j.appender.<b>stdout</b>=org.apache.log4j.ConsoleAppender
|
|
|
|
|
|
|
|
log4j.appender.<b>stdout</b>.layout=org.apache.log4j.PatternLayout
|
2018-02-28 07:58:59 +01:00
|
|
|
log4j.appender.<b>stdout</b>.layout.ConversionPattern=<span style="color:blue"><b>%m%n</b></span>
|
2005-03-21 18:14:21 +00:00
|
|
|
</pre>
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>This configuration creates an output channel (<q>Appender</q>) to console named as <code>stdout</code> which prints
|
|
|
|
the message (<q>%m</q>) followed by a line feed (<q>%n</q>)—same as the earlier <code>System.out.println()</code>
|
|
|
|
:-) Oooh kay—but we haven't finished yet. We should deliver the configuration file, too. So we change the
|
|
|
|
buildfile:</p>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
...
|
|
|
|
<target name="compile">
|
|
|
|
<mkdir dir="${classes.dir}"/>
|
|
|
|
<javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
|
|
|
|
<b><copy todir="${classes.dir}"></b>
|
|
|
|
<b><fileset dir="${src.dir}" excludes="**/*.java"/></b>
|
|
|
|
<b></copy></b>
|
|
|
|
</target>
|
2018-02-28 07:58:59 +01:00
|
|
|
...</pre>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>This copies all resources (as long as they haven't the suffix <samp>.java</samp>) to the build directory, so we could
|
2005-03-21 18:14:21 +00:00
|
|
|
start the application from that directory and these files will included into the jar.</p>
|
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="junit">Testing the class</h2>
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>In this step we will introduce the usage of the JUnit [3] test framework in combination with Ant. Because Ant has a
|
|
|
|
built-in JUnit 4.12 you could start directly using it. Write a test class in <samp>src\HelloWorldTest.java</samp>:</p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
2018-02-28 07:58:59 +01:00
|
|
|
import org.junit.Test;
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
public class HelloWorldTest {
|
|
|
|
|
|
|
|
@Test
|
2006-07-11 08:38:58 +00:00
|
|
|
public void testNothing() {
|
|
|
|
}
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
@Test
|
2006-07-11 08:38:58 +00:00
|
|
|
public void testWillAlwaysFail() {
|
|
|
|
fail("An error message");
|
|
|
|
}
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
}</pre>
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Because we don't have real business logic to test, this test class is very small: just show how to start. For further
|
|
|
|
information see the JUnit documentation [3] and the manual of <a href="Tasks/junit.html">junit</a> task. Now we add a
|
|
|
|
junit instruction to our buildfile:</p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
...
|
|
|
|
|
2011-04-20 04:57:23 +00:00
|
|
|
<path <b>id="application"</b> location="${jar.dir}/${ant.project.name}.jar"/>
|
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<target name="run" depends="jar">
|
|
|
|
<java fork="true" classname="${main-class}">
|
|
|
|
<classpath>
|
|
|
|
<path refid="classpath"/>
|
2011-04-20 04:57:23 +00:00
|
|
|
<b><path refid="application"/></b>
|
2006-07-11 08:38:58 +00:00
|
|
|
</classpath>
|
|
|
|
</java>
|
|
|
|
</target>
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<b><target name="junit" depends="jar">
|
|
|
|
<junit printsummary="yes">
|
|
|
|
<classpath>
|
|
|
|
<path refid="classpath"/>
|
|
|
|
<path refid="application"/>
|
|
|
|
</classpath>
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<batchtest fork="yes">
|
|
|
|
<fileset dir="${src.dir}" includes="*Test.java"/>
|
|
|
|
</batchtest>
|
|
|
|
</junit>
|
|
|
|
</target></b>
|
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
...</pre>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>We reuse the path to our own jar file as defined in run-target by giving it an ID and making it globally available.
|
|
|
|
The <code>printsummary=yes</code> lets us see more detailed information than just a "FAILED" or "PASSED" message. How
|
|
|
|
much tests failed? Some errors? <var>printsummary</var> lets us know. The classpath is set up to find our classes. To
|
|
|
|
run tests the <code>batchtest</code> here is used, so you could easily add more test classes in the future just by
|
|
|
|
naming them <code>*Test.java</code>. This is a common naming scheme.</p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>After a <code>ant junit</code> you'll get:</p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
|
|
|
<pre class="output">
|
|
|
|
...
|
|
|
|
junit:
|
|
|
|
[junit] Running HelloWorldTest
|
|
|
|
[junit] Tests run: 2, Failures: 1, Errors: 0, Time elapsed: 0,01 sec
|
|
|
|
[junit] Test HelloWorldTest FAILED
|
|
|
|
|
|
|
|
BUILD SUCCESSFUL
|
2018-02-28 07:58:59 +01:00
|
|
|
...</pre>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>We can also produce a report. Something that you (and other) could read after closing the shell .... There are two
|
|
|
|
steps: 1. let <code><junit></code> log the information and 2. convert these to something readable (browsable).<p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
...
|
|
|
|
<b><property name="report.dir" value="${build.dir}/junitreport"/></b>
|
|
|
|
...
|
|
|
|
<target name="junit" depends="jar">
|
|
|
|
<b><mkdir dir="${report.dir}"/></b>
|
|
|
|
<junit printsummary="yes">
|
|
|
|
<classpath>
|
|
|
|
<path refid="classpath"/>
|
|
|
|
<path refid="application"/>
|
|
|
|
</classpath>
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<b><formatter type="xml"/></b>
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<batchtest fork="yes" <b>todir="${report.dir}"</b>>
|
|
|
|
<fileset dir="${src.dir}" includes="*Test.java"/>
|
|
|
|
</batchtest>
|
|
|
|
</junit>
|
|
|
|
</target>
|
2018-02-08 22:52:33 +01:00
|
|
|
|
2006-07-11 08:38:58 +00:00
|
|
|
<b><target name="junitreport">
|
|
|
|
<junitreport todir="${report.dir}">
|
|
|
|
<fileset dir="${report.dir}" includes="TEST-*.xml"/>
|
|
|
|
<report todir="${report.dir}"/>
|
|
|
|
</junitreport>
|
2018-02-28 07:58:59 +01:00
|
|
|
</target></b></pre>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-28 07:58:59 +01:00
|
|
|
<p>Because we would produce a lot of files and these files would be written to the current directory by default, we
|
|
|
|
define a report directory, create it before running the <q>junit</q> and redirect the logging to it. The log format is
|
|
|
|
XML so <q>junitreport</q> could parse it. In a second target <q>junitreport</q> should create a browsable HTML report
|
|
|
|
for all generated XML log files in the report directory. Now you can open the <samp>${report.dir}\index.html</samp> and
|
|
|
|
see the result (looks something like JavaDoc).<br> Personally I use two different targets
|
|
|
|
for <code><junit></code> and <code><junitreport></code>. Generating the HTML report needs some time and you
|
|
|
|
don't need the HTML report just for testing, e.g. if you are fixing an error or a integration server is doing a job.</p>
|
2006-07-11 08:38:58 +00:00
|
|
|
|
2018-02-08 22:52:33 +01:00
|
|
|
<h2 id="resources">Resources</h2>
|
2018-02-09 06:54:03 +01:00
|
|
|
<ol class="refs">
|
2018-02-28 07:58:59 +01:00
|
|
|
<li><a href="https://archive.apache.org/dist/logging/log4j/1.2.17/logging-log4j-1.2.17.zip">https://archive.apache.org/dist/logging/log4j/1.2.17/logging-log4j-1.2.17.zip</a></li>
|
|
|
|
<li><a href="https://logging.apache.org/log4j/1.2/manual.html">https://logging.apache.org/log4j/1.2/manual.html</a></li>
|
|
|
|
<li><a href="https://junit.org/junit4">https://junit.org/junit4</a></li>
|
2018-02-09 06:54:03 +01:00
|
|
|
</ol>
|
2005-06-04 07:34:02 +00:00
|
|
|
|
2005-03-21 18:14:21 +00:00
|
|
|
</body>
|
2006-08-14 23:24:03 +00:00
|
|
|
</html>
|