diff --git a/WHATSNEW b/WHATSNEW index 838b65e1c..ba3f1721f 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -289,6 +289,11 @@ Other changes: * has new attributes failonerror and showoutput attributes. +* Added two tutorials + - beginner: introduction into Ant + - task developers: using path, fileset etc + + Fixed bugs: ----------- diff --git a/docs/manual/developlist.html b/docs/manual/developlist.html index 3cd0c7ea4..801090f73 100644 --- a/docs/manual/developlist.html +++ b/docs/manual/developlist.html @@ -21,9 +21,10 @@ Source-code Integration
InputHandler
Using Ant Tasks Outside of Ant
-
-Tutorial: Writing Tasks
-Tutorial: Tasks using Properties, Filesets & Paths
+
Tutorials
+Hello World with Ant
+Writing Tasks
+Tasks using Properties, Filesets & Paths
diff --git a/docs/manual/tutorial-HelloWorldWithAnt.html b/docs/manual/tutorial-HelloWorldWithAnt.html new file mode 100644 index 000000000..7fdc88600 --- /dev/null +++ b/docs/manual/tutorial-HelloWorldWithAnt.html @@ -0,0 +1,314 @@ + + + Tutorial: Hello World with Ant + + + + +

Tutorial: Hello World with Ant

+ +

This document provides a step by step tutorial for starting java programming with Ant. +It does not contain deeper knowledge about Java or Ant. This tutorial has the goal +to let you see, how to do the easiest steps in Ant.

+ + + +

Content

+

+ + + + +

Preparing the project

+

We want to separate the source from the generated files, so our java source files will +be in src folder. All generated files should be under build, and there +splitted into several subdirectories for the individual steps: classes for our compiled +files and jar for our own JAR-file.

+

The later directories are created by our buildfile, so we have to create only the src +directory. (Because I am working on Windows, here is the win-syntax - translate to your shell):

+ +
+md src
+
+ +

This is not a Java tutorial, so just write this code into src/oata/HelloWorld.java - +you should guess it's meaning ;-)

+ +
+package oata;
+
+public class HelloWorld {
+    public static void main(String[] args) {
+        System.out.println("Hello World");
+    }
+}
+
+ + + + +

Four steps to a running application

+

Oki-doki - now we have to think about our build process. We have to compile our code, otherwise we couldn't +start the program. Oh - "start" - yes, we could provide a target for that. We should 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" :-)

+ +

The buildfile describing that would be:

+
+<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>
+
+ +

Now you can compile, package and run the application via

+
+ant compile
+ant jar
+ant run
+
+

Or shorter with

+
+ant compile jar run
+
+ + + + +

Enhance the build file

+

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.

+

The first and second point would be adressed with properties, the thirs with a special property - an attribute +of the <project>-tag and the fourth problem can be solved using dependencies.

+ +
+<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>
+
+ +

Now it's easier, just do a ant and you will get

+
+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
+
+ + + +

Using external libraries

+

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

+

We store our external libraries in a new directory lib. Log4J can be +downloaded from Logging's Homepage. +Create the lib 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. +

+

Working with Log4J is documented inside its manual. Here we use the MyApp-example from the +Short Manual. First we have to modify the java source to +use the logging framework:

+ +
+package oata;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.BasicConfigurator;
+
+public class HelloWorld {
+    static Logger logger = Logger.getLogger(HelloWorld.class);
+
+    public static void main(String[] args) {
+        BasicConfigurator.configure();
+        logger.info("Hello World");
+    }
+}
+
+ +

Most of the modifications are "framework overhead" which has to be done once. The red line is our "old System-out" +statement.

+

Don't try to run ant - 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:

+ +
+<project name="HelloWorld" basedir="." default="main">
+    ...
+    <property name="lib.dir"     value="lib"/>
+
+    <path id="classpath">
+        <fileset dir="${lib.dir}" includes="**/*.jar"/>
+    </path>
+
+    ...
+
+    <target name="compile">
+        <mkdir dir="${classes.dir}"/>
+        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
+    </target>
+
+    <target name="run" depends="jar">
+        <java fork="true" classname="${main-class}">
+            <classpath>
+                <path refid="classpath"/>
+                <path location="${jar.dir}/${ant.project.name}.jar"/>
+            </classpath>
+        </java>
+    </target>
+
+    ...
+
+</project>
+
+ +

In this example we start our application not via its Main-Class manifest-attribute, because we could not provide +a jarname and a classpath. So add our class in the red line to the already defined path and start as usual. Running +ant would give (after the usual compile stuff):

+ +
+[java] 0 [main] INFO oata.HelloWorld  - Hello World
+
+ +

What's that?

+For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.

+ + + +

Configuration files

+

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 BasicConfigurator.configure(); 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 src/log4j.properties. +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!

+ +
+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
+
+ +

This configuration creates an output channel ("Appender") to console named as stdout 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:

+ +
+    ...
+    <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>
+    ...
+
+ +

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.

+ +
+

Copyright © 2005 The Apache Software Foundation. All rights Reserved.

+ + + \ No newline at end of file