Development and Build System with ANT - Case Study: Building the Technology Conference Management System with Ant
(Page 7 of 11 )
To set the stage for the development throughout the rest of the book, you need to first create a suitable directory structure (see Figure 3-5) as well as an initial Ant buildfile for the TCMS system.

Figure 3-5. Sample directory structure for the TCMS project
The project’s root directory is tcms. Under this directory you’ll place the project’s main buildfile named build.xml. The subdirectories under tcms are organized as follows:
- lib: Contains any libraries required at runtime by the application(s).
- lib/development: Contains any libraries required at development time.
- src: The root directory for all nongenerated sources.
- src/java: The root directory for all Java sources.
From the previous directory structure, it should be clear that you must take measures to differentiate the needs of the application at development or build time vs. the needs of the runtime environment.
Now that you have a suitable directory structure, your next step should be to start putting together the tcms buildfile. The project element contains the name of your project and a nested description element.
BEST PRACTICE
Use the project element nested description. This description is shown on the console when invoking Ant with the -projecthelp command-line option.
The default target will be the all target, which you’ll develop later in the chapter. The basedir is set to be the directory where the buildfile resides, which in this case is the tcms directory.
<?xml version="1.0"?>
<project
name="Enterprise Java Development on a Budget"
default="all"
basedir="."
>
<description>
This build script was developed to be a generic enterprise development
build script using ANT 1.5.3 (ant.apache.org). To customize it or use it for
other projects modify the build.properties file.
</description>
...
Next, properties are defined for the created directories. Notice that you can define properties using other properties as with the lib-dev property. Properties that represent a directory are defined using the location attribute instead of the value attribute. The location attribute gets resolved to the full path relative to the basedir specified in the project element.
BEST PRACTICE
Making all paths relative to the project’s basedir directory and avoiding the use of absolute paths guarantees that your buildfile will work anywhere. If your build depends on a resource whose location might change from environment to environment, you should place the location of said resource in a properties file or use environment variables such as ${os.name}.
The build directory is the root directory for all products of the build process, such as the classes directory, where the results of compiling the classes under src/java will be placed.
<!-- ====================================================== -->
<!-- Initialization
-->
<!-- ====================================================== -->
<property name="build" location="build"/>
<property name="lib" location="lib"/>
<property name="lib-dev" location="${lib}/development"/>
<!-- Directories -->
<property name="src" location="src"/>
<property name="src-java" location="${src}/java"/> <property name="classes" location="${build}/classes"/> <property name="docs" location="docs"/>
<property name="api" location="${docs}/api"/>
Paths representing all the JAR files under the lib directory (class.path) and all class files under the classes directory are created.
BEST PRACTICE
A common practice in Ant buildfiles is to have an init task that all other tasks depend on. We advocate not using the init task for setting up properties, loading properties files, paths, patternsets, or taskdefs. Instead just place them before the first target and they will be added to the implicit target. As mentioned earlier, the contents of the implicit target always get called and you don’t have to remember making all other targets dependent on an init target.
A patternset is also used to filter a directory for nonsource files. In the case where resources are part of the source directory, such as property files or images, you can use a patternset to copy them to the location of the compiled classes, which will require said resources.
<!-- Paths -->
<path id="class.path">
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
</path>
<path id="app.class.path">
<pathelement location="${classes}"/>
<path refid="class.path"/>
</path>
<!-- Patternsets -->
<patternset id="non.source.set">
<exclude name="**/*.java"/>
...
<exclude name="**/read-me.txt"/>
<exclude name="**/package.html"/>
</patternset>
Compiling Now it’s time to add the first target to the buildfile, the compile target. This target will make use of the javac task, which is a wrapper to the javac command. Notice that before the javac task is invoked, all files under the ${src-java} directory that match the patternset non.source.set are copied to the ${classes} directory. This is done so that any resources such as Java properties files, images, and others are available to the compiled code under the classes directory. This is a common practice for many IDEs.
<!-- ====================================================== -->
<!-- Compiles all the classes
-->
<!-- ====================================================== -->
<target
name="compile"
depends="compile-init"
description="Compiles all classes.">
<javac
destdir="${classes}"
classpathref="class.path"
debug="on"
deprecation="on"
optimize="off"
>
<src>
<path refid="ejb.source.path"/>
</src>
</javac>
<!-- copy non-source resources only if the compilation is successful -->
<copy todir="${classes}">
<fileset dir="${src-java}">
<patternset refid="non.source.set"/>
</fileset>
</copy>
</target>
<target name="compile-init">
<mkdir dir="${classes}"/>
</target>
<target name="compile-clean">
<delete dir="${classes}"/>
</target>
Notice that you added two more targets other than compile. These are compile-init and compile-clean. The compile-init target simply creates the classes directory by making use of the mkdir task. The compile-clean uses the delete task to remove the directory and all of its contents.
BEST PRACTICE
For each main target in the buildfile, add a target-init and a target-clean, where target is the name of the main target. This makes it fairly straightforward to determine the resources needed and created by a target and also makes it easier to maintain large buildfiles. For simple buildfiles a single clean target will usually suffice.
Next: JavaDoc Generation >>
More Java Articles
More By Apress Publishing
|
This article is taken from chapter three of the book Enterprise Java Development on a Budget, written by Brian Sam-Bodden and Christopher M. Judd (Apress, 2004; ISBN: 1590591259). Check it out at your favorite bookstore today. Buy this book now.
|
|