On Wed, Apr 11, 2001 at 01:48:37PM -0700, Craig R. McClanahan wrote:
> In looking at the build.xml files for components created so far, I'd like
> to suggest some common practices based on what seems to work well.  If we
> started converging on these practices, then we can codify them in
> guidelines for new Commons committers so they don't have to struggle to
> figure out how we do things.
> 
> Note that these guidelines would certainly be useful within
> jakarta-commons-sandbox as well as jakarta-commons -- but we've explicitly
> said that the sandbox has few or no rules, so the "official" guidelines
> should apply to jakarta-commons only.
> 
> To help us towards the goal of similar implementations across components,
> I've got the following suggestions for us to consider and comment on:
> 
> 
> (1) Reliance on Ant Installation
> 
> Cactus and Beanutils expect you to have installed your favorite version of
> Ant, including setting ANT_HOME and adding $ANT_HOME/bin to your PATH.  In
> addition, you will need to install any optional tasks (and JAR files they
> depend on) in $ANT_HOME/lib.  This approach means we don't need to create
> "build.bat" and "build.sh" scripts -- we can just execute "ant" directly
> to run our builds.

Hooray.. no more dodgy scripts to maintain :) Although see caveats below.

> (2) Ant Library Dependencies
> 
> Ant supports the ability to configure the set of JAR files it uses in the
> $ANT_HOME/lib directory.  At least for the present, can we encourage
> people to configure like this?
> - Ant 1.3 or later (affects what commands you can use in build.xml files).
> - Install the corresponding optional.jar file.
> - Replace the JAXP/1.0 parser (jaxp.jar and parser.jar) with the
>   JAXP/1.1 stuff (jaxp.jar, crimson.jar, and xalan.jar).  This makes
>   things like the <style> task work, and will become the norm in
>   Ant 1.4.
> - Other JARs needed here should be documented in the instructions for
>   the Commons component that needs them (although see my separate rant
>   about stylebook :-).

Ah yes.. just an additional point, the Ant <stylebook> task *requires* an
earlier version of xalan (1.2.2 I think). This is not the version bundled with
JAXP1.1, and certainly not anything from xalan 2.x. I had to fish out the
xalan.jar from Cocoon to get Cactus compiling.

This is a cactus-specific example of a more general problem with the Antless
approach. See below..

> (3) CLASSPATH Assumptions
> 
> To the maximum extent feasible, build.xml scripts should make zero
> assumptions about the contents of the developer's CLASSPATH (or
> assumptions about what has been installed in the $JAVA_HOME/jre/lib/ext
> directory on Java2 systems).  A good way to test this is to explicitly
> unset your CLASSPATH, and make sure all the targets in your build.xml
> script work correctly.

Yes! Classpath variables are evil ;)

> Note that this requires mechanisms for declaring external dependencies --
> see below for suggestions.
> 
> 
> (4) Source Directory Structure
> 
> The following directory layout will be typical for a Commons component:
> 
> jakarta-commons/foo/             For component "foo"
>   build/                         BUILD SCRIPTS
>     build.xml                    Standard build.xml script (with others
>                                  if appropriate)
>     build.properties.sample      Example external dependencies file (see
>                                  below for details)
>   conf/                          CONFIGURATION FILE SOURCES
>     MANIFEST.MF                  Manifest file for JAR(s)
>   dist/                          (OUTPUT) BINARY DISTRIBUTION
>     conf/                        Static configuration files
>     docs/                        Documentation other than JavaDocs
>     javadoc/                     JavaDoc API docs
>     lib/                         JAR file(s) containing the component
>     src/                         Copy of CVS source repository (?)
>   docs/ (or xdocs/)              DOCUMENTATION OTHER THAN JAVADOCS
>   src/                           SOURCE CODE MODULES
>     java/                        Java sources (or "share") - may be >1
>     test/                        Unit test sources (same package
>                                  hierarchy as "java")
>   target/                        (OUTPUT) BUILD DESTINATION
>     classes/                     Compiled classes for component itself
>     conf/                        Configuration files (possibly filtered)
>     tests/                       Compiled classes for unit tests
>   web/                           WEB APPLICATION SOURCES (IF RELEVANT)

Most of the world uses "build" as the directory where built stuff is kept.
Velocity is the only exception I know of, and it makes sense there because
Velocity comes with a version of Ant.

Since Ant is now an external dependency, and build.(sh|bat) has been
eliminated, there won't be many files in "build" anyway. Why not just keep
build.xml and build.properties in the project root? That way, it's immediately
obvious how to get started. It also eliminates the potential confusion from
having basedir=".." in the build.xml.

[snip lots of good stuff]

> (9) Declaring External Dependencies
[..]

Here's a problem with the "don't bundle Ant" approach:

There are now two kind of external dependencies:
 - Ant must have been compiled with support for relevant optional tasks
 - The supporting jars for optional tasks must be *in the classpath*.

As an example, let's say build.xml uses <stylebook>. For this to work, the user
needs stylebook's jars *in their classpath* (not in build.properties). Because
we've eliminated build.(sh|bat), and don't bundle Ant jars, we cannot prevent
users from getting cryptic "org.apache.* not found" errors if they:
 - have not compiled Ant with whatever optional task this project needs
 - have not manually added the optional task's jars to their classpath

So these external dependencies need to be documented, in big flashing lights. I
suggest adding an INSTALL file to your project template for this.

However, since most people don't read INSTALL docs till after it's all gone wrong:

If an Ant target uses optional tasks, it should have a mechanism where the
requisite classes are checked for with <depends>, and an informative message
printed if those classes aren't found.


--Jeff

> Craig McClanahan

Reply via email to