source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/docs/manual/tutorial-HelloWorldWithAnt.html@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 11.3 KB
Line 
1<html>
2<head>
3 <title>Tutorial: Hello World with Ant</title>
4 <meta name="author" content="Jan Mat&egrave;rne">
5 <style type="text/css">
6 <!--
7 .code { background: #EFEFEF; margin-top: }
8 .output { color: #FFFFFF; background: #837A67; }
9 -->
10 </style>
11</head>
12<body>
13<h1>Tutorial: Hello World with Ant</h1>
14
15<p>This document provides a step by step tutorial for starting java programming with Ant.
16It does <b>not</b> contain deeper knowledge about Java or Ant. This tutorial has the goal
17to let you see, how to do the easiest steps in Ant.</p>
18
19
20
21<h2>Content</h2>
22<p><ul>
23<li><a href="#prepare">Preparing the project</a></li>
24<li><a href="#four-steps">Enhance the build file</a></li>
25<li><a href="#enhance">Enhance the build file</a></li>
26<li><a href="#ext-libs">Using external libraries</a></li>
27</ul></p>
28
29
30
31<a name="prepare"></a>
32<h2>Preparing the project</h2>
33<p>We want to separate the source from the generated files, so our java source files will
34be in <tt>src</tt> folder. All generated files should be under <tt>build</tt>, and there
35splitted into several subdirectories for the individual steps: <tt>classes</tt> for our compiled
36files and <tt>jar</tt> for our own JAR-file.</p>
37<p>The later directories are created by our buildfile, so we have to create only the <tt>src</tt>
38directory. (Because I am working on Windows, here is the win-syntax - translate to your shell):</p>
39
40<pre class="code">
41md src
42</pre>
43
44<p>This is not a Java tutorial, so just write this code into <tt>src/oata/HelloWorld.java</tt> -
45you should guess it's meaning ;-)</p>
46
47<pre class="code">
48package oata;
49
50public class HelloWorld {
51 public static void main(String[] args) {
52 System.out.println("Hello World");
53 }
54}
55</pre>
56
57
58
59<a name="four-steps"></a>
60<h2>Four steps to a running application</h2>
61<p>Oki-doki - now we have to think about our build process. We <i>have</i> to compile our code, otherwise we couldn't
62start the program. Oh - "start" - yes, we could provide a target for that. We <i>should</i> package our application.
63Now it's only one class - but if you want to provide a download, no one would download several hundreds files ...
64(think about a complex Swing GUI :) - so let us create a jar file. A startable jar file would be nice ... And it's a
65good practise to have a "clean" target, which deletes all the generated stuff. Many failures could be solved just
66by a "clean build" :-)</p>
67
68<p>The buildfile describing that would be:</p>
69<pre class="code">
70&lt;project&gt;
71
72 &lt;target name="clean"&gt;
73 &lt;delete dir="build"/&gt;
74 &lt;/target&gt;
75
76 &lt;target name="compile"&gt;
77 &lt;mkdir dir="build/classes"/&gt;
78 &lt;javac srcdir="src" destdir="build/classes"/&gt;
79 &lt;/target&gt;
80
81 &lt;target name="jar"&gt;
82 &lt;mkdir dir="build/jar"/&gt;
83 &lt;jar destfile="build/jar/HelloWorld.jar" basedir="build/classes"&gt;
84 &lt;manifest&gt;
85 &lt;attribute name="Main-Class" value="oata.HelloWorld"/&gt;
86 &lt;/manifest&gt;
87 &lt;/jar&gt;
88 &lt;/target&gt;
89
90 &lt;target name="run"&gt;
91 &lt;java jar="build/jar/HelloWorld.jar" fork="true"/&gt;
92 &lt;/target&gt;
93
94&lt;/project&gt;
95</pre>
96
97<p>Now you can compile, package and run the application via</p>
98<pre class="code">
99ant compile
100ant jar
101ant run
102</pre>
103<p>Or shorter with</p>
104<pre class="code">
105ant compile jar run
106</pre>
107
108
109
110<a name="enhance"></a>
111<h2>Enhance the build file</h2>
112</p>Ok, the build works - but it is not as nice as it should: many time you are referencing the same directories,
113main-class and jar-name are hard coded, and while invocation you have to remember the right order of build steps.</p>
114<p>The first and second point would be adressed with <i>properties</i>, the thirs with a special property - an attribute
115of the &lt;project&gt;-tag and the fourth problem can be solved using dependencies.</p>
116
117<pre class="code">
118&lt;project name="HelloWorld" basedir="." default="main"&gt;
119
120 &lt;property name="src.dir" value="src"/&gt;
121
122 &lt;property name="build.dir" value="build"/&gt;
123 &lt;property name="classes.dir" value="${build.dir}/classes"/&gt;
124 &lt;property name="jar.dir" value="${build.dir}/jar"/&gt;
125
126 &lt;property name="main-class" value="oata.HelloWorld"/&gt;
127
128
129
130 &lt;target name="clean"&gt;
131 &lt;delete dir="${build.dir}"/&gt;
132 &lt;/target&gt;
133
134 &lt;target name="compile"&gt;
135 &lt;mkdir dir="${classes.dir}"/&gt;
136 &lt;javac srcdir="${src.dir}" destdir="${classes.dir}"/&gt;
137 &lt;/target&gt;
138
139 &lt;target name="jar" depends="compile"&gt;
140 &lt;mkdir dir="${jar.dir}"/&gt;
141 &lt;jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}"&gt;
142 &lt;manifest&gt;
143 &lt;attribute name="Main-Class" value="${main-class}"/&gt;
144 &lt;/manifest&gt;
145 &lt;/jar&gt;
146 &lt;/target&gt;
147
148 &lt;target name="run" depends="jar"&gt;
149 &lt;java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/&gt;
150 &lt;/target&gt;
151
152 &lt;target name="clean-build" depends="clean,jar"/&gt;
153
154 &lt;target name="main" depends="clean,run"/&gt;
155
156&lt;/project&gt;
157</pre>
158
159<p>Now it's easier, just do a <tt>ant</tt> and you will get</p>
160<pre class="output">
161Buildfile: build.xml
162
163clean:
164
165compile:
166 [mkdir] Created dir: C:\...\build\classes
167 [javac] Compiling 1 source file to C:\...\build\classes
168
169jar:
170 [mkdir] Created dir: C:\...\build\jar
171 [jar] Building jar: C:\...\build\jar\HelloWorld.jar
172
173run:
174 [java] Hello World
175
176main:
177
178BUILD SUCCESSFUL
179</pre>
180
181
182<a name="ext-libs"></a>
183<h2>Using external libraries</h2>
184<p>Somehow told us not to use syso-statements. For log-Statements we should use a Logging-API - customizable on a high
185degree (including switching off during usual life (= not development) execution). We use Log4J, because <ul>
186<li>it is not part of the JDK (1.4+) and we want to show how to use external libs</li>
187<li>it can run under JDK 1.2 (as Ant)</li>
188<li>it's highly configurable</li>
189<li>it's from Apache :-)</li>
190</ul></p>
191<p>We store our external libraries in a new directory <tt>lib</tt>. Log4J can be
192<a href="http://www.apache.org/dist/logging/log4j/1.2.9/logging-log4j-1.2.9.zip">downloaded</a> from Logging's Homepage.
193Create the <tt>lib</tt> directory and extract the log4j-1.2.9.jar into that lib-directory. After that we have to modify
194our java source to use that library and our buildfile so that this library could be accessed during compilation and run.
195</p>
196<p>Working with Log4J is documented inside its manual. Here we use the <i>MyApp</i>-example from the
197<a href="http://logging.apache.org/log4j/docs/manual.html">Short Manual</a>. First we have to modify the java source to
198use the logging framework:</p>
199
200<pre class="code">
201package oata;
202
203<b>import org.apache.log4j.Logger;</b>
204<b>import org.apache.log4j.BasicConfigurator;</b>
205
206public class HelloWorld {
207 <b>static Logger logger = Logger.getLogger(HelloWorld.class);</b>
208
209 public static void main(String[] args) {
210 <b>BasicConfigurator.configure();</b>
211 <font color="blue"><b>logger.info("Hello World");</b></font>
212 }
213}
214</pre>
215
216<p>Most of the modifications are "framework overhead" which has to be done once. The red line is our "old System-out"
217statement.</p>
218<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
219to do a little work here. But do not change the CLASSPATH environment variable! This is only for this project and maybe
220you would break other environments (this is one of the most famous mistakes when working with Ant). We introduce Log4J
221into our buildfile:</p>
222
223<pre class="code">
224&lt;project name="HelloWorld" basedir="." default="main"&gt;
225 ...
226 <b>&lt;property name="lib.dir" value="lib"/&gt;</b>
227
228 <b>&lt;path id="classpath"&gt;</b>
229 <b>&lt;fileset dir="${lib.dir}" includes="**/*.jar"/&gt;</b>
230 <b>&lt;/path&gt;</b>
231
232 ...
233
234 &lt;target name="compile"&gt;
235 &lt;mkdir dir="${classes.dir}"/&gt;
236 &lt;javac srcdir="${src.dir}" destdir="${classes.dir}" <b>classpathref="classpath"</b>/&gt;
237 &lt;/target&gt;
238
239 &lt;target name="run" depends="jar"&gt;
240 &lt;java fork="true" <b>classname="${main-class}"</b>&gt;
241 <b>&lt;classpath&gt;</b>
242 <b>&lt;path refid="classpath"/&gt;</b>
243 <font color="blue"><b>&lt;path location="${jar.dir}/${ant.project.name}.jar"/&gt;</b></font>
244 <b>&lt;/classpath&gt;</b>
245 &lt;/java&gt;
246 &lt;/target&gt;
247
248 ...
249
250&lt;/project&gt;
251</pre>
252
253<p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide
254a jarname <i>and</i> a classpath. So add our class in the red line to the already defined path and start as usual. Running
255<tt>ant</tt> would give (after the usual compile stuff):</p>
256
257<pre class="output">
258[java] 0 [main] INFO oata.HelloWorld - Hello World
259</pre>
260
261<p>What's that? <ul>
262<li><i>[java]</i> Ant task running at the moment</li>
263<li><i>0</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
264<li><i>[main]</i> the running thread from our application </li>
265<li><i>INFO</i> log level of that statement</i>
266<li><i>oata.HelloWorld</i> source of that statement</i>
267<li><i>-</i> <font size="-1">sorry don't know - some Log4J stuff</font></li>
268<li><i>Hello World</i> the message</li>
269</ul>
270For another layout ... have a look inside Log4J's documentation about using other PatternLayout's.</p>
271
272
273<a name="config-files">
274<h2>Configuration files</h2>
275<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
276ours. We had coded <tt>BasicConfigurator.configure();</tt> which implies a simple, but hard coded configuration. More
277confortable would be using a property file. In the java source delete the BasicConfiguration-line from the main() method.
278Log4J will search then for a configuration as described in it's manual. Then create a new file <tt>src/log4j.properties</tt>.
279That's the default name for Log4J's configuration and using that name would make life easier - not only the framework knows
280what is inside, you too!</p>
281
282<pre class="code">
283log4j.rootLogger=DEBUG, <b>stdout</b>
284
285log4j.appender.<b>stdout</b>=org.apache.log4j.ConsoleAppender
286
287log4j.appender.<b>stdout</b>.layout=org.apache.log4j.PatternLayout
288log4j.appender.<b>stdout</b>.layout.ConversionPattern=<font color="blue"><b>%m%n</b></font>
289</pre>
290
291<p>This configuration creates an output channel ("Appender") to console named as <tt>stdout</tt> which prints the
292message (%m) followed by a line feed (%n) - same as the earlier System.out.println() :-) Oooh kay - but we haven't
293finished yet. We should deliver the configuration file, too. So we change the buildfile:</p>
294
295<pre class="code">
296 ...
297 &lt;target name="compile"&gt;
298 &lt;mkdir dir="${classes.dir}"/&gt;
299 &lt;javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/&gt;
300 <b>&lt;copy todir="${classes.dir}"&gt;</b>
301 <b>&lt;fileset dir="${src.dir}" excludes="**/*.java"/&gt;</b>
302 <b>&lt;/copy&gt;</b>
303 &lt;/target&gt;
304 ...
305</pre>
306
307<p>This copies all resources (as long as they haven't the suffix ".java") to the build directory, so we could
308start the application from that directory and these files will included into the jar.</p>
309
310<hr>
311<p align="center">Copyright &copy; 2005 The Apache Software Foundation. All rights Reserved.</p>
312
313</body>
314</html>
Note: See TracBrowser for help on using the repository browser.