Design Concepts

   This document summarizes some of the basic concepts embodied in all the JWare/AntXtras Foundation products. We explain these ideas and our terminology here to help you understand the AntXtras User Guide, Developer documents, and source code structure. The information here is the latest edition of the “Basic Concepts Explained” section of the original v1 AntXtra’s Quick Start Guide.

Execution Cycle

In much of the public documentation, Ant is largely described in terms of a project with discreet targets and tasks. Ant targets and projects are effectively static; they don’t do anything by themselves. When a user runs Ant, the project and the selected target(s) combine and become the local fixture in which sets of instructions, the Ant tasks, are executed. At least, this is Ant’s view of the universe.

From the Ant user’s perspective, the project but especially the selected target’s name represents the overall task to be accomplished, or goal. This is why user-selected Ant targets are often named to reflect the reason for or side effects of executing the target’s tasks. So, interestingly, from the user’s point of view the selected target is the task—that Ant actually executes instructions across multiple JVMs, projects, and other targets is of little importance as long as the original request is serviced.

AntXtras calls this repeated request servicing the execution cycle. A single execution cycle begins when the user or source system invokes Ant. An execution cycle transcends the multiple Ant projects, targets, and tasks that might be created and used before it reaches its end. The JWare/AntXtras Foundation project contains rudimentary support classes that ensure that cycle-scoped information can be created and managed properly. However, only a few Foundation tasks (called configuration tasksets) actually embody any cycle level control. To really leverage the value of the execution cycle you should look at some of the AntXtras-based sub-projects like Akimabu or SAMS.

Remote Observability

One of the primary objectives of the current AntXtras architecture is to facilitate the ability to observe a remote execution cycle as it begins, progresses, and ends. Such an ability allows you to both monitor automated builds and deployments for problems as well as create other applications that utilize the by-products of the various steps executed during an execution cycle.

An execution cycle’s feedback comes from two sources: the Ant runtime implementation, and the explicit information broadcast by you the script author. When Ant displays every target that is called, that is one form of feedback. When Ant executes an <echo> instruction that you have included, that is another form of feedback. AntXtras is primarily concerned with the second of the two forms; the one you control explicitly. Because AntXtras does not change the core Ant implementation, it cannot alter when or what messages are emitted from Ant’s infrastructure. These messages must be controlled with the facilities that Ant itself provides: configurable build listeners, various run options, etc.

AntXtras (and its Log4Ant and SAMS sub-projects) contains several feedback tasks of which <show>, <emit:show>, <emit:checkpoint>, and <sams:announce> are the most important. Collectively these tasks allow you to broadcast events and to describe an execution cycle’s state in great detail to any interested monitor.

Feedback Noise Levels

AntXtras and its sub-projects provide several execution feedback tasks. Associated with each of these feedback tasks is a noise level— the level of importance associated with the event that triggered the feedback. Like the standard Ant <echo> task, the term “noise level” is often abbreviated to just “level.” AntXtras supports six noise levels: FATAL, ERROR, WARNING, INFO, VERBOSE, and DEBUG. These six levels represent a super-set of the set supported by the standard Ant logging infrastructure. When using the Ant logging system, the AntXtras FATAL level is mapped to the Ant ERROR level automatically.

Within the Ant runtime, a noise level is only used to filter output to the log streams. However, when AntXtras is combined with a logging system like Log4J or LOGBack, the noise level can trigger more complex responses like email notification, or persistence in a run report database. In this scenario, how the monitor responds to a particular event is configured independent of the Ant script and its command options (which could be fixed if the system is automated).

Scoped Configuration

By default, the Ant environment provides you with a single collection of write-once/read-many-times controls, called properties, as the primary tool to configure the Ant runtime fixture1). Generally, global properties are a good thing. However, there are times that you want to affect only the fixture only while a specific set of tasks execution without affecting subsequently executed tasks. AntXtras calls this sort of control, scoped configuration. Scoped configuration is most often applied at the execution cycle level where it affects all enclosed, executed tasks, regardless of their declared project or target. AntXtras includes several tasks that let you create scoped configuration; for example <overlay>, <isolate>, and <overlaymessages>.

Do not confuse AntXtras’s scoped configuration with Ant macro definitions (<macrodef>s) and preset-definitions (<presetdef>s). Both these Ant items let you create custom, optionally parameterized, tasks and meta-tasks without proliferating “internal” top-level targets in an attempt to create some level of modularity. In contrast, AntXtras’s scoped configuration tasks help you alter the Ant runtime’s fixture temporarily, for whatever reason; they do not make Ant task definition easier in any way. AntXtra’s configuration tasks can help you modularize your Ant script’s workflow particularly if your goal involves running many independent, non-trivial activities.

Bubbles and Nets

Within AntXtras there are two special kinds of scoped configuration tasks: bubbles and nets. You use bubbles to isolate the effect of the enclosed tasks on the project’s environment without creating a sub-project that must re-parse the original build file. The AntXtras <isolate> task is one example of a bubble task. Nets, on the other hand, are used to filter existing or overlay custom fixture information read by the enclosed tasks. Unlike a bubble task, a net task will allow certain modifications through to the current project’s environment while it blocks other information from being seen or modified. The AntXtras <overlay> task is an example of a net task.

TaskSets

Many of the AntXtras tasks are defined as task containers we call tasksets. A taskset (itself a task) usually overlays some kind of configuration or enforces some kind of control over its nested tasks; we call these nested tasks the taskset’s scope of control. Because tasksets are also tasks, tasksets can be nested.

Ordinarily, for a taskset to be effective at least one nested task must be defined. However, most tasksets will function as harmless no-ops if left empty; those that do not will signal an exception when executed. Every AntXtras scoped configuration task is a taskset; its configuration only applies to its nested tasks. Empty configuration tasksets do not modify the current fixture in any way.

A taskset’s nested tasks are not configured until the controlling taskset says so. This means property expansion may not occur until the taskset is actually executed which is usually the desired behavior. Tasksets that are selectively executed by other tasks as called quiet tasksets. One example of a quiet taskset is the <iferror> taskset which is executed only if its controlling <protect> taskset detects an error has occurred.

Starting with Ant 1.6, task containers can contain freestanding data declarations like classpaths or filters as well as other tasks. Just like data declared at the top-level or target-level, declarations that include an Ant “id” attribute are visible to all tasks within the same project; however, the surrounding taskset must be executed in order for the data to be defined fully.

Conditional Execution

Ant supports a rudimentary, conditional execution capability based on the existence of a property (or lack thereof). Conditional execution is supported by all Ant targets and a few standard tasks using two attributes: “if” and “unless”. Ant’s preferred method for you to control what gets done is for you to control the data that operations are applied against using its vast collection of set definition components and features. AntXtras supports and extends these capabilities with three new flow-control tasksets: <do>, <domatch>, and <dowhile>— no other AntXtras flow-control task supports conditional execution directly unless it’s necessary to maintain compatibility with existing Ant tasks. We also make sure that AntXtras components work with the native Ant set definition features where useful.

We limit condition execution to just these tasksets for two reasons. First, it keeps things simple for us folks writing new Ant scripts and for those maintaining old ones. To introduce and alter a condition for running one or more tasks, you simply drop them inside one of the AntXtras “do” tasksets with the appropriate condition parameters attached. Second, it keeps things simple for us, the AntXtras developers, because it limits the number of classes we must update and test to support new (or remove old) condition parameters.

Editable Properties (aka Variables)

Ant’s project properties are write-once; once defined, they cannot be modified or removed. Generally, write-once properties suit their intended purpose but they can be troublesome in many situations. The AntXtras “bubbles” and “nets” task containers alleviate some of the problems, but there are many situations where using a overlay is either heavy-handed, impractical, or just unsuitable. AntXtras created a script-accessible mutable property called a variable property or just a variable to address exactly these cases.

Variables solve some many common issues with write-once properties; issues like manipulating loop cursors, or controlling build meta data like build numbers, task duration, and status flags between otherwise independent sub-builds. In general, if an AntXtras task can read or create property values, it can also read and write variable property values instead.

Variable properties are also called exported properties because they can exist at the execution cycle level, the thread level, or the project level (like references).

Flexible Value Substitution

The standard Ant environment supports a simple property-based value substitution mechanism. Any component’s attributes can be defined in terms of existing property values but /the source properties must exist when the attributes’ owning element is configured. While tolerable for task declarations that are often configured just before being executed(once), this limitation significantly reduces the flexibility of globally declared, shareable data objects. Because Ant’s data objects are never executed, they are configured as their script declarations are parsed. This means if you reference a property in a global data item’s attributes, that property must exist before the data item is configured, not before it is used.

Ant 1.6 introduced task macros and delayed configuration for target-bound items which alleviated some of the obvious “chicken before the egg” problems with simple property substitution. But neither macros nor delayed configuration address the need for per-use property substitution in global data objects. Even some of the new data objects, like <propertyset>, have task-specific “recalculate” options to workaround the problem.

AntXtras components extend the standard Ant substitution mechanism with something called Flexible Value declarations. Flexible values enable attribute value substitution to occur when a data item is used or when a task is executed. Moreover, an attribute’s value can be defined as a literal value, a property value, a variable value, or a reference’s string representation. This flexibility allows you to define shared data like templates— the actual values of properties, variables, etc. are determined when the data is used, not by its location in the Ant script.

URL-Based Locations

To ensure that you can use AntXtras in a distributed (and diverse) development and support environment, almost every AntXtras component that accepts data or configuration from an external source, lets you specify that source using a standard URL format or Java resource format. This flexibility lets you execute your AntXtras scripts with data that resides in local files, in classpath-specified jar files, on remote HTTP servers, or any another other data store that you can access using a URL-encoded extraction string (like a database with a jdbc:/ URL or a Subversion item with a svn:/ URL). Many of AntXtras tasks also let you save location information in the form of URLs.

Function Shortcuts

Starting with 0.5, AntXtras supports a special kind of property value called a function shortcut or funcut (v1 actually called these value URIs). A function shortcut is a short hand way of executing a builtin Ant or AntXtras function using the standard property reference syntax. Among its many uses, function shortcuts let you chain task calls without creating lots of transient project properties to hold intermediate values. The final string value of the funcut is whatever the executed function returns; for example, the $shorttime: funcut will return a formatted time string of the current time while the $filenotempty: funcut returns “true” if the named file is empty or does not exist and “false” otherwise. AntXtras comes with its own function shortcut antlib but you can extend the set with your own shortcut handler classes; see the AntXtras javadocs for additional information.

Environment and Error Snapshots

AntXtras aims to make writing error-tolerant and auto-correcting Ant scripts easier and to this end it provides several error-handling mechanisms in its components. However, when a scripttr-stopping error does occur AntXtras also provides a device that captures environment information (including the actual exception) and a means for passing that information to logs, run monitors, and any custom build listeners. This device is called an environment or error snapshot and is usually created by the AntXtras <protect> taskset when it detects a build exception has been thrown by one of its nested tasks.

Although it is not required, you can explicitly define what an error snapshot contains and what bits of a snapshot gets passed-on to monitors and other build listeners. Currently snapshots can contain execution cycle fixture information like execution-location, properties, references, and component definitions. (You can extend this base function greatly with the Log4Ant AntXtras antlib.) Every AntXtras feedback task can display or broadcast error snapshots.

1) Actually there are three kinds of properties: user, inherited, and regular for lack of another term. These properties primarily differ in how Ant propagates them to child projects. Their other differences are not formally exposed through standard Ant tasks in any way. Most tasks create regular properties. From a property-read perspective (the build script author’s perspective), the three types appear as a single source.

Navigation
Personal Tools