Home -> Professional -> Component Build
Maven is a very good, powerful way to build a Java product, that can handle a product divided into projects. Unfortunately, not all products are able to use Maven, for whatever reason (company policies, difficult learning curve, etc.). Maven also has a few requirements that don't always fit the natural shape of a product. Ant, on the other hand, is a simpler, more widely accepted way to build a Java product. It works at a lower level than Maven, and so often requires more work to achieve the same results.
When a codebase becomes larger, it becomes more and more painful to build the whole product. It would be helpful to have a "component" build, in Ant, that allows the developers to work on one part of the codebase while allowing the rest of the codebase to be nearly ignored. Once the source has been partitioned into the appropriate chunks, how do we get Ant to build the right way?
A component build should:
One directory structure that supports some of the goals is:
branch/-- The top of the build system; a convenient place to check out files from the source code repository.
branch/topbuild-- The "top build" component, containing the build scripts and supporting files (libraries, configurations, etc.) for the entire product.
branch/component-- The top of each component, containing source, build scripts, supporting files, and all else needed for a single component.
branch/component/src-- The source directory. Everything that becomes part of the distributed product from this component belongs somewhere under here, so that this is the only directory that needs to be checked to see if changes have been made that force a rebuild. Subdirectories are named for the type of source.
branch/component/src/java-- The java source directory. All java files that qualify as source have their path start under this directory. For a product whose files live in packages "com.mycompany...", there would be a "com". directory under this one.
branch/component/src/web-- The web source directory. All files used directly to build a web archive (.war, .ear, etc.), such as HTML, JSP, manifests, etc., belong here, in a directory structure that mirrors the structure within the archive.
branch/component/src/conf-- The configuration source directory. All configuration files that end up in the distributed product belong somewhere under here.
branch/component/test-- The test directory. Everything that is used to run automated tests belongs under this directory. The subdirectories are named for the type of test artifact contained.
branch/component/test/java-- The java test directory. This directory contains all unit tests and other tests that are used with this component.
branch/component/test/data-- The test data directory. This directory contains all files needed by unit tests or other tests.
branch/component/test/conf-- The test configuration directory. This directory contains all configuration files needed by unit tests or other tests.
branch/component/build-- The build directory. When compiled, linked, assembled, or otherwise transformed into some intermediate form, the results are stored here in an appropriate directory structure. The build's "clean" target deletes this directory, so nothing permanent should be here.
branch/component/testbuild-- The test build directory. When compiled, linked, assembled, or otherwise transformed into usable form, the test executables are stored here in an appropriate directory structure. Tests are run using this directory or specific subdirectories as classpath nodes, or using .jar files in this directory on the classpath. The build's "clean" target deletes this directory, so nothing permanent should be here.
branch/component/dist-- The distribution directory. The component's distributable artifacts go here. They should be few in number, generally. This directory is the only directory from which other components may satisfy their dependencies. The build's "clean" target deletes this directory, so nothing permanent should be here.
The rest of this discussion assumes such a directory structure. While there are other perfectly good directory structures, this one is assumed so that the following arguments don't have to digress into handling all the other possibilities. It should be easy enough to modify the component build ideas to work with other directory structures (and if it isn't, that's probably a defect in the directory structure).
There are two types of build script in this design: Top-level build, and component
build. The top-level build gets its own "component" directory
branch/topbuild), and each component gets its own eponymous
Also, note that the examples here are simplified build scripts. The output is simple .jar files, instead of .war or .ear files, directories of Java classes, combined java and native code, or whatever else may be needed. The marker file and check file approach to preventing unnecessary build steps has no impact on, and is not affected by, the type of build output. Neither are they affected if the build is enhanced with library dependency checking, other types of tests, style checking, static code analysis, continuous integration, etc.
The master build file, the one that should be invoked by default when
the user types "ant" at the command line. Thus, it should be included as
Anyone who tries to use this build script, or very attentive readers, may
have noticed that it imports another file,
header.xml. It is found
in the same directory as the master build file, as
The topbuild directory also contains some Ant scripts that are used in the
component builds. This one defines the standard classpaths used for building
the source, and for building and running unit tests. It is found at
dependency.xml script is included in any component build
script whose component depends on one or more other components. It establishes
several targets that are needed to allow the component to act as a dependency
and to use others as dependencies. It is found at
nodependency.xml script is included in any component build
script whose component does not depend on any other components. It establishes
several targets that are needed to allow the component to act as a dependency.
It is found at
Components with no dependencies have a build file that does not look for
dependencies. The build script is placed at the top of the component's
|build.xml (no dependencies)|
Components with dependencies have a build file that can trigger a build for the
dependencies as well. The build script is placed at the top of the component's
Copyright © 2004-2010, Leif Bennett. All rights reserved.