2005-03-21 18:14:21 +00:00
|
|
|
|
<html>
|
|
|
|
|
<head>
|
|
|
|
|
<title>Tutorial: Hello World with Ant</title>
|
2005-06-04 07:34:02 +00:00
|
|
|
|
<meta name="author" content="Jan Mat<61>rne">
|
2005-03-21 18:14:21 +00:00
|
|
|
|
<style type="text/css">
|
|
|
|
|
<!--
|
|
|
|
|
.code { background: #EFEFEF; margin-top: }
|
|
|
|
|
.output { color: #FFFFFF; background: #837A67; }
|
|
|
|
|
-->
|
|
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<h1>Tutorial: Hello World with Ant</h1>
|
|
|
|
|
|
|
|
|
|
<p>This document provides a step by step tutorial for starting java programming with Ant.
|
|
|
|
|
It does <b>not</b> 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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Content</h2>
|
|
|
|
|
<p><ul>
|
|
|
|
|
<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>
|
2005-03-21 18:14:21 +00:00
|
|
|
|
</ul></p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="prepare"></a>
|
|
|
|
|
<h2>Preparing the project</h2>
|
|
|
|
|
<p>We want to separate the source from the generated files, so our java source files will
|
|
|
|
|
be in <tt>src</tt> folder. All generated files should be under <tt>build</tt>, and there
|
|
|
|
|
splitted into several subdirectories for the individual steps: <tt>classes</tt> for our compiled
|
|
|
|
|
files and <tt>jar</tt> for our own JAR-file.</p>
|
|
|
|
|
<p>The later directories are created by our buildfile, so we have to create only the <tt>src</tt>
|
|
|
|
|
directory. (Because I am working on Windows, here is the win-syntax - translate to your shell):</p>
|
|
|
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
|
md src
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>This is not a Java tutorial, so just write this code into <tt>src/oata/HelloWorld.java</tt> -
|
|
|
|
|
you should guess it's meaning ;-)</p>
|
|
|
|
|
|
|
|
|
|
<pre class="code">
|
|
|
|
|
package oata;
|
|
|
|
|
|
|
|
|
|
public class HelloWorld {
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
System.out.println("Hello World");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="four-steps"></a>
|
|
|
|
|
<h2>Four steps to a running application</h2>
|
|
|
|
|
<p>Oki-doki - now we have to think about our build process. We <i>have</i> to compile our code, otherwise we couldn't
|
|
|
|
|
start the program. Oh - "start" - yes, we could provide a target for that. We <i>should</i> 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 "clean" target, which deletes all the generated stuff. Many failures could be solved just
|
|
|
|
|
by a "clean build" :-)</p>
|
|
|
|
|
|
|
|
|
|
<p>The buildfile describing that would be:</p>
|
|
|
|
|
<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>
|
|
|
|
|
|
|
|
|
|
</project>
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Now you can compile, package and run the application via</p>
|
|
|
|
|
<pre class="code">
|
|
|
|
|
ant compile
|
|
|
|
|
ant jar
|
|
|
|
|
ant run
|
|
|
|
|
</pre>
|
|
|
|
|
<p>Or shorter with</p>
|
|
|
|
|
<pre class="code">
|
|
|
|
|
ant compile jar run
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="enhance"></a>
|
|
|
|
|
<h2>Enhance the build file</h2>
|
|
|
|
|
</p>Ok, the build works - but it is not as nice as it should: many time you are referencing the same directories,
|
|
|
|
|
main-class and jar-name are hard coded, and while invocation you have to remember the right order of build steps.</p>
|
|
|
|
|
<p>The first and second point would be adressed with <i>properties</i>, the thirs with a special property - an attribute
|
|
|
|
|
of the <project>-tag and the fourth problem can be solved using dependencies.</p>
|
|
|
|
|
|
|
|
|
|
<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"/>
|
|
|
|
|
|
|
|
|
|
</project>
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Now it's easier, just do a <tt>ant</tt> and you will get</p>
|
|
|
|
|
<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:
|
|
|
|
|
|
|
|
|
|
BUILD SUCCESSFUL
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="ext-libs"></a>
|
|
|
|
|
<h2>Using external libraries</h2>
|
|
|
|
|
<p>Somehow told us not to use syso-statements. For log-Statements we should use a Logging-API - customizable on a high
|
|
|
|
|
degree (including switching off during usual life (= not development) execution). We use Log4J, because <ul>
|
|
|
|
|
<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>
|
|
|
|
|
<li>it's from Apache :-)</li>
|
|
|
|
|
</ul></p>
|
|
|
|
|
<p>We store our external libraries in a new directory <tt>lib</tt>. Log4J can be
|
2005-06-04 07:34:02 +00:00
|
|
|
|
<a href="http://www.apache.org/dist/logging/log4j/1.2.9/logging-log4j-1.2.9.zip">downloaded [1]</a> from Logging's Homepage.
|
2005-03-21 18:14:21 +00:00
|
|
|
|
Create the <tt>lib</tt> directory and extract the log4j-1.2.9.jar into that lib-directory. After that we have to modify
|
|
|
|
|
our java source 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 <i>MyApp</i>-example from the
|
2005-06-04 07:34:02 +00:00
|
|
|
|
<a href="http://logging.apache.org/log4j/docs/manual.html">Short Manual [2]</a>. First we have to modify the java source to
|
2005-03-21 18:14:21 +00:00
|
|
|
|
use the logging framework:</p>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
<font color="blue"><b>logger.info("Hello World");</b></font>
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>Most of the modifications are "framework overhead" which has to be done once. The red line is our "old System-out"
|
|
|
|
|
statement.</p>
|
|
|
|
|
<p>Don't try to run <tt>ant</tt> - you will only get lot of compiler errors. Log4J is not inside the classpath so we have
|
|
|
|
|
to do a little work here. But do not change the CLASSPATH 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
|
|
|
|
|
into our buildfile:</p>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
<font color="blue"><b><path location="${jar.dir}/${ant.project.name}.jar"/></b></font>
|
|
|
|
|
<b></classpath></b>
|
|
|
|
|
</java>
|
|
|
|
|
</target>
|
|
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
</project>
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide
|
|
|
|
|
a jarname <i>and</i> a classpath. So add our class in the red line to the already defined path and start as usual. Running
|
|
|
|
|
<tt>ant</tt> would give (after the usual compile stuff):</p>
|
|
|
|
|
|
|
|
|
|
<pre class="output">
|
|
|
|
|
[java] 0 [main] INFO oata.HelloWorld - Hello World
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>What's that? <ul>
|
|
|
|
|
<li><i>[java]</i> Ant task running at the moment</li>
|
|
|
|
|
<li><i>0</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
|
|
|
|
|
<li><i>[main]</i> the running thread from our application </li>
|
|
|
|
|
<li><i>INFO</i> log level of that statement</i>
|
|
|
|
|
<li><i>oata.HelloWorld</i> source of that statement</i>
|
|
|
|
|
<li><i>-</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
|
|
|
|
|
<li><i>Hello World</i> the message</li>
|
|
|
|
|
</ul>
|
|
|
|
|
For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<a name="config-files">
|
|
|
|
|
<h2>Configuration files</h2>
|
|
|
|
|
<p>Why we have used Log4J? "It's highly configurable"? No - all is hard coded! But that is not the debt of Log4J - it's
|
|
|
|
|
ours. We had coded <tt>BasicConfigurator.configure();</tt> which implies a simple, but hard coded configuration. More
|
|
|
|
|
confortable would be using a property file. In the java source delete the BasicConfiguration-line from the main() method.
|
|
|
|
|
Log4J will search then for a configuration as described in it's manual. Then create a new file <tt>src/log4j.properties</tt>.
|
|
|
|
|
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>
|
|
|
|
|
|
|
|
|
|
<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
|
|
|
|
|
log4j.appender.<b>stdout</b>.layout.ConversionPattern=<font color="blue"><b>%m%n</b></font>
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>This configuration creates an output channel ("Appender") to console named as <tt>stdout</tt> which prints the
|
|
|
|
|
message (%m) followed by a line feed (%n) - same as the earlier System.out.println() :-) Oooh kay - but we haven't
|
|
|
|
|
finished yet. We should deliver the configuration file, too. So we change the buildfile:</p>
|
|
|
|
|
|
|
|
|
|
<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>
|
|
|
|
|
...
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
<p>This copies all resources (as long as they haven't the suffix ".java") to the build directory, so we could
|
|
|
|
|
start the application from that directory and these files will included into the jar.</p>
|
|
|
|
|
|
2005-06-04 07:34:02 +00:00
|
|
|
|
|
|
|
|
|
<a name="resources"></a>
|
|
|
|
|
<h2>Resources</h2>
|
|
|
|
|
<pre>
|
|
|
|
|
[1] <a href="http://www.apache.org/dist/logging/log4j/1.2.9/logging-log4j-1.2.9.zip">http://www.apache.org/dist/logging/log4j/1.2.9/logging-log4j-1.2.9.zip</a>
|
|
|
|
|
[2] <a href="http://logging.apache.org/log4j/docs/manual.html">http://logging.apache.org/log4j/docs/manual.html</a>
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
2005-03-21 18:14:21 +00:00
|
|
|
|
<hr>
|
|
|
|
|
<p align="center">Copyright © 2005 The Apache Software Foundation. All rights Reserved.</p>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|