1 | <html>
|
---|
2 | <head>
|
---|
3 | <title>Tutorial: Hello World with Ant</title>
|
---|
4 | <meta name="author" content="Jan Matè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.
|
---|
16 | It does <b>not</b> contain deeper knowledge about Java or Ant. This tutorial has the goal
|
---|
17 | to 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
|
---|
34 | be in <tt>src</tt> folder. All generated files should be under <tt>build</tt>, and there
|
---|
35 | splitted into several subdirectories for the individual steps: <tt>classes</tt> for our compiled
|
---|
36 | files 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>
|
---|
38 | directory. (Because I am working on Windows, here is the win-syntax - translate to your shell):</p>
|
---|
39 |
|
---|
40 | <pre class="code">
|
---|
41 | md src
|
---|
42 | </pre>
|
---|
43 |
|
---|
44 | <p>This is not a Java tutorial, so just write this code into <tt>src/oata/HelloWorld.java</tt> -
|
---|
45 | you should guess it's meaning ;-)</p>
|
---|
46 |
|
---|
47 | <pre class="code">
|
---|
48 | package oata;
|
---|
49 |
|
---|
50 | public 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
|
---|
62 | start the program. Oh - "start" - yes, we could provide a target for that. We <i>should</i> package our application.
|
---|
63 | Now 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
|
---|
65 | good practise to have a "clean" target, which deletes all the generated stuff. Many failures could be solved just
|
---|
66 | by a "clean build" :-)</p>
|
---|
67 |
|
---|
68 | <p>The buildfile describing that would be:</p>
|
---|
69 | <pre class="code">
|
---|
70 | <project>
|
---|
71 |
|
---|
72 | <target name="clean">
|
---|
73 | <delete dir="build"/>
|
---|
74 | </target>
|
---|
75 |
|
---|
76 | <target name="compile">
|
---|
77 | <mkdir dir="build/classes"/>
|
---|
78 | <javac srcdir="src" destdir="build/classes"/>
|
---|
79 | </target>
|
---|
80 |
|
---|
81 | <target name="jar">
|
---|
82 | <mkdir dir="build/jar"/>
|
---|
83 | <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
|
---|
84 | <manifest>
|
---|
85 | <attribute name="Main-Class" value="oata.HelloWorld"/>
|
---|
86 | </manifest>
|
---|
87 | </jar>
|
---|
88 | </target>
|
---|
89 |
|
---|
90 | <target name="run">
|
---|
91 | <java jar="build/jar/HelloWorld.jar" fork="true"/>
|
---|
92 | </target>
|
---|
93 |
|
---|
94 | </project>
|
---|
95 | </pre>
|
---|
96 |
|
---|
97 | <p>Now you can compile, package and run the application via</p>
|
---|
98 | <pre class="code">
|
---|
99 | ant compile
|
---|
100 | ant jar
|
---|
101 | ant run
|
---|
102 | </pre>
|
---|
103 | <p>Or shorter with</p>
|
---|
104 | <pre class="code">
|
---|
105 | ant 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,
|
---|
113 | main-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
|
---|
115 | of the <project>-tag and the fourth problem can be solved using dependencies.</p>
|
---|
116 |
|
---|
117 | <pre class="code">
|
---|
118 | <project name="HelloWorld" basedir="." default="main">
|
---|
119 |
|
---|
120 | <property name="src.dir" value="src"/>
|
---|
121 |
|
---|
122 | <property name="build.dir" value="build"/>
|
---|
123 | <property name="classes.dir" value="${build.dir}/classes"/>
|
---|
124 | <property name="jar.dir" value="${build.dir}/jar"/>
|
---|
125 |
|
---|
126 | <property name="main-class" value="oata.HelloWorld"/>
|
---|
127 |
|
---|
128 |
|
---|
129 |
|
---|
130 | <target name="clean">
|
---|
131 | <delete dir="${build.dir}"/>
|
---|
132 | </target>
|
---|
133 |
|
---|
134 | <target name="compile">
|
---|
135 | <mkdir dir="${classes.dir}"/>
|
---|
136 | <javac srcdir="${src.dir}" destdir="${classes.dir}"/>
|
---|
137 | </target>
|
---|
138 |
|
---|
139 | <target name="jar" depends="compile">
|
---|
140 | <mkdir dir="${jar.dir}"/>
|
---|
141 | <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
|
---|
142 | <manifest>
|
---|
143 | <attribute name="Main-Class" value="${main-class}"/>
|
---|
144 | </manifest>
|
---|
145 | </jar>
|
---|
146 | </target>
|
---|
147 |
|
---|
148 | <target name="run" depends="jar">
|
---|
149 | <java jar="${jar.dir}/${ant.project.name}.jar" fork="true"/>
|
---|
150 | </target>
|
---|
151 |
|
---|
152 | <target name="clean-build" depends="clean,jar"/>
|
---|
153 |
|
---|
154 | <target name="main" depends="clean,run"/>
|
---|
155 |
|
---|
156 | </project>
|
---|
157 | </pre>
|
---|
158 |
|
---|
159 | <p>Now it's easier, just do a <tt>ant</tt> and you will get</p>
|
---|
160 | <pre class="output">
|
---|
161 | Buildfile: build.xml
|
---|
162 |
|
---|
163 | clean:
|
---|
164 |
|
---|
165 | compile:
|
---|
166 | [mkdir] Created dir: C:\...\build\classes
|
---|
167 | [javac] Compiling 1 source file to C:\...\build\classes
|
---|
168 |
|
---|
169 | jar:
|
---|
170 | [mkdir] Created dir: C:\...\build\jar
|
---|
171 | [jar] Building jar: C:\...\build\jar\HelloWorld.jar
|
---|
172 |
|
---|
173 | run:
|
---|
174 | [java] Hello World
|
---|
175 |
|
---|
176 | main:
|
---|
177 |
|
---|
178 | BUILD 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
|
---|
185 | degree (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.
|
---|
193 | Create the <tt>lib</tt> directory and extract the log4j-1.2.9.jar into that lib-directory. After that we have to modify
|
---|
194 | our 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
|
---|
198 | use the logging framework:</p>
|
---|
199 |
|
---|
200 | <pre class="code">
|
---|
201 | package oata;
|
---|
202 |
|
---|
203 | <b>import org.apache.log4j.Logger;</b>
|
---|
204 | <b>import org.apache.log4j.BasicConfigurator;</b>
|
---|
205 |
|
---|
206 | public 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"
|
---|
217 | statement.</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
|
---|
219 | to do a little work here. But do not change the CLASSPATH environment variable! This is only for this project and maybe
|
---|
220 | you would break other environments (this is one of the most famous mistakes when working with Ant). We introduce Log4J
|
---|
221 | into our buildfile:</p>
|
---|
222 |
|
---|
223 | <pre class="code">
|
---|
224 | <project name="HelloWorld" basedir="." default="main">
|
---|
225 | ...
|
---|
226 | <b><property name="lib.dir" value="lib"/></b>
|
---|
227 |
|
---|
228 | <b><path id="classpath"></b>
|
---|
229 | <b><fileset dir="${lib.dir}" includes="**/*.jar"/></b>
|
---|
230 | <b></path></b>
|
---|
231 |
|
---|
232 | ...
|
---|
233 |
|
---|
234 | <target name="compile">
|
---|
235 | <mkdir dir="${classes.dir}"/>
|
---|
236 | <javac srcdir="${src.dir}" destdir="${classes.dir}" <b>classpathref="classpath"</b>/>
|
---|
237 | </target>
|
---|
238 |
|
---|
239 | <target name="run" depends="jar">
|
---|
240 | <java fork="true" <b>classname="${main-class}"</b>>
|
---|
241 | <b><classpath></b>
|
---|
242 | <b><path refid="classpath"/></b>
|
---|
243 | <font color="blue"><b><path location="${jar.dir}/${ant.project.name}.jar"/></b></font>
|
---|
244 | <b></classpath></b>
|
---|
245 | </java>
|
---|
246 | </target>
|
---|
247 |
|
---|
248 | ...
|
---|
249 |
|
---|
250 | </project>
|
---|
251 | </pre>
|
---|
252 |
|
---|
253 | <p>In this example we start our application not via its Main-Class manifest-attribute, because we could not provide
|
---|
254 | 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
|
---|
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>
|
---|
270 | For 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
|
---|
276 | ours. We had coded <tt>BasicConfigurator.configure();</tt> which implies a simple, but hard coded configuration. More
|
---|
277 | confortable would be using a property file. In the java source delete the BasicConfiguration-line from the main() method.
|
---|
278 | Log4J will search then for a configuration as described in it's manual. Then create a new file <tt>src/log4j.properties</tt>.
|
---|
279 | That's the default name for Log4J's configuration and using that name would make life easier - not only the framework knows
|
---|
280 | what is inside, you too!</p>
|
---|
281 |
|
---|
282 | <pre class="code">
|
---|
283 | log4j.rootLogger=DEBUG, <b>stdout</b>
|
---|
284 |
|
---|
285 | log4j.appender.<b>stdout</b>=org.apache.log4j.ConsoleAppender
|
---|
286 |
|
---|
287 | log4j.appender.<b>stdout</b>.layout=org.apache.log4j.PatternLayout
|
---|
288 | log4j.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
|
---|
292 | message (%m) followed by a line feed (%n) - same as the earlier System.out.println() :-) Oooh kay - but we haven't
|
---|
293 | finished yet. We should deliver the configuration file, too. So we change the buildfile:</p>
|
---|
294 |
|
---|
295 | <pre class="code">
|
---|
296 | ...
|
---|
297 | <target name="compile">
|
---|
298 | <mkdir dir="${classes.dir}"/>
|
---|
299 | <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
|
---|
300 | <b><copy todir="${classes.dir}"></b>
|
---|
301 | <b><fileset dir="${src.dir}" excludes="**/*.java"/></b>
|
---|
302 | <b></copy></b>
|
---|
303 | </target>
|
---|
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
|
---|
308 | start the application from that directory and these files will included into the jar.</p>
|
---|
309 |
|
---|
310 | <hr>
|
---|
311 | <p align="center">Copyright © 2005 The Apache Software Foundation. All rights Reserved.</p>
|
---|
312 |
|
---|
313 | </body>
|
---|
314 | </html> |
---|