git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272920 13f79535-47bb-0310-9956-ffa450edef68master
@@ -2,19 +2,19 @@ | |||||
<!-- Content Stylesheet for Site --> | <!-- Content Stylesheet for Site --> | ||||
<!-- start the processing --> | <!-- start the processing --> | ||||
<html> | <html> | ||||
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | ||||
<meta name="author" value="Conor MacNeill"> | <meta name="author" value="Conor MacNeill"> | ||||
<meta name="email" value=""> | <meta name="email" value=""> | ||||
<title>The Jakarta Site - Mutant Design Notes</title> | |||||
<title>Mutant Proposal - Mutant Design Notes</title> | |||||
</head> | </head> | ||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | <table border="0" width="100%" cellspacing="0"> | ||||
<!-- TOP IMAGE --> | <!-- TOP IMAGE --> | ||||
<tr> | <tr> | ||||
@@ -27,58 +27,21 @@ | |||||
<tr><td colspan="2"> | <tr><td colspan="2"> | ||||
<hr noshade="" size="1"/> | <hr noshade="" size="1"/> | ||||
</td></tr> | </td></tr> | ||||
<tr> | <tr> | ||||
<!-- LEFT SIDE NAVIGATION --> | <!-- LEFT SIDE NAVIGATION --> | ||||
<td valign="top" nowrap="true"> | <td valign="top" nowrap="true"> | ||||
<p><strong>Apache Ant</strong></p> | |||||
<ul> | |||||
<li> <a href="./index.html">Front Page</a> | |||||
</li> | |||||
<li> <a href="./antnews.html">News</a> | |||||
</li> | |||||
<li> <a href="./manual/index.html">Documentation</a> | |||||
</li> | |||||
<li> <a href="./external.html">External Tools and Tasks</a> | |||||
</li> | |||||
<li> <a href="./resources.html">Resources</a> | |||||
</li> | |||||
<li> <a href="./faq.html">Ant FAQ</a> | |||||
</li> | |||||
<li> <a href="./problems.html">Having Problems?</a> | |||||
</li> | |||||
</ul> | |||||
<p><strong>Download</strong></p> | |||||
<ul> | |||||
<li> <a href="http://jakarta.apache.org/site/binindex.html">Binaries</a> | |||||
</li> | |||||
<li> <a href="http://jakarta.apache.org/site/sourceindex.html">Source Code</a> | |||||
</li> | |||||
</ul> | |||||
<p><strong>Jakarta</strong></p> | |||||
<ul> | |||||
<li> <a href="http://jakarta.apache.org/site/news.html">News & Status</a> | |||||
</li> | |||||
<li> <a href="http://jakarta.apache.org/site/mission.html">Mission</a> | |||||
</li> | |||||
<li> <a href="http://jakarta.apache.org/site/guidelines.html">Guidelines Notes</a> | |||||
</li> | |||||
<li> <a href="http://jakarta.apache.org/site/faqs.html">FAQs</a> | |||||
</li> | |||||
</ul> | |||||
<p><strong>Get Involved</strong></p> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | <ul> | ||||
<li> <a href="http://jakarta.apache.org/site/getinvolved.html">Overview</a> | |||||
</li> | |||||
<li> <a href="http://jakarta.apache.org/site/cvsindex.html">CVS Repositories</a> | |||||
<li> <a href="./index.html">Introduction</a> | |||||
</li> | </li> | ||||
<li> <a href="http://jakarta.apache.org/site/mail.html">Mailing Lists</a> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | </li> | ||||
<li> <a href="http://jakarta.apache.org/site/library.html">Reference Library</a> | |||||
<li> <a href="./features.html">User Features</a> | |||||
</li> | </li> | ||||
<li> <a href="http://nagoya.apache.org/bugzilla/enter_bug.cgi?product=Ant">Bug Database</a> | |||||
<li> <a href="./developers.html">Task Developers</a> | |||||
</li> | </li> | ||||
<li> <a href="http://nagoya.apache.org/bugzilla/enter_bug.cgi?product=Ant&bug_severity=Enhancement">Enhancement Requests</a> | |||||
<li> <a href="./design.html">Design Description</a> | |||||
</li> | </li> | ||||
</ul> | </ul> | ||||
</td> | </td> | ||||
@@ -0,0 +1,82 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
<!-- Content Stylesheet for Site --> | |||||
<!-- start the processing --> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |||||
<meta name="author" value="Conor MacNeill"> | |||||
<meta name="email" value=""> | |||||
<title>Mutant Proposal - Developers</title> | |||||
</head> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | |||||
<!-- TOP IMAGE --> | |||||
<tr> | |||||
<td colspan="2"> | |||||
<a href="http://jakarta.apache.org"><img src="http://jakarta.apache.org/images/jakarta-logo.gif" align="left" border="0"/></a> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
<table border="0" width="100%" cellspacing="4"> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr> | |||||
<!-- LEFT SIDE NAVIGATION --> | |||||
<td valign="top" nowrap="true"> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | |||||
<li> <a href="./index.html">Introduction</a> | |||||
</li> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | |||||
<li> <a href="./features.html">User Features</a> | |||||
</li> | |||||
<li> <a href="./developers.html">Task Developers</a> | |||||
</li> | |||||
<li> <a href="./design.html">Design Description</a> | |||||
</li> | |||||
</ul> | |||||
</td> | |||||
<td align="left" valign="top"> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Developers"><strong>Developers</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
This page will describe the design of Mutant's core. | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<!-- FOOTER --> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr><td colspan="2"> | |||||
<div align="center"><font color="#525D76" size="-1"><em> | |||||
Copyright © 2000-2002, Apache Software Foundation | |||||
</em></font></div> | |||||
</td></tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
<!-- end the processing --> | |||||
@@ -0,0 +1,82 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
<!-- Content Stylesheet for Site --> | |||||
<!-- start the processing --> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |||||
<meta name="author" value="Conor MacNeill"> | |||||
<meta name="email" value=""> | |||||
<title>Mutant Proposal - Developers</title> | |||||
</head> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | |||||
<!-- TOP IMAGE --> | |||||
<tr> | |||||
<td colspan="2"> | |||||
<a href="http://jakarta.apache.org"><img src="http://jakarta.apache.org/images/jakarta-logo.gif" align="left" border="0"/></a> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
<table border="0" width="100%" cellspacing="4"> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr> | |||||
<!-- LEFT SIDE NAVIGATION --> | |||||
<td valign="top" nowrap="true"> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | |||||
<li> <a href="./index.html">Introduction</a> | |||||
</li> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | |||||
<li> <a href="./features.html">User Features</a> | |||||
</li> | |||||
<li> <a href="./developers.html">Task Developers</a> | |||||
</li> | |||||
<li> <a href="./design.html">Design Description</a> | |||||
</li> | |||||
</ul> | |||||
</td> | |||||
<td align="left" valign="top"> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Developers"><strong>Developers</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
This page will describe the operation of Mutant from a task developers perspective. | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<!-- FOOTER --> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr><td colspan="2"> | |||||
<div align="center"><font color="#525D76" size="-1"><em> | |||||
Copyright © 2000-2002, Apache Software Foundation | |||||
</em></font></div> | |||||
</td></tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
<!-- end the processing --> | |||||
@@ -0,0 +1,867 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
<!-- Content Stylesheet for Site --> | |||||
<!-- start the processing --> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |||||
<meta name="author" value="Conor MacNeill"> | |||||
<meta name="email" value=""> | |||||
<title>Mutant Proposal - Mutant Goals</title> | |||||
</head> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | |||||
<!-- TOP IMAGE --> | |||||
<tr> | |||||
<td colspan="2"> | |||||
<a href="http://jakarta.apache.org"><img src="http://jakarta.apache.org/images/jakarta-logo.gif" align="left" border="0"/></a> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
<table border="0" width="100%" cellspacing="4"> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr> | |||||
<!-- LEFT SIDE NAVIGATION --> | |||||
<td valign="top" nowrap="true"> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | |||||
<li> <a href="./index.html">Introduction</a> | |||||
</li> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | |||||
<li> <a href="./features.html">User Features</a> | |||||
</li> | |||||
<li> <a href="./developers.html">Task Developers</a> | |||||
</li> | |||||
<li> <a href="./design.html">Design Description</a> | |||||
</li> | |||||
</ul> | |||||
</td> | |||||
<td align="left" valign="top"> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Goals"><strong>Goals</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
This page describes the key goals that have shaped the development of | |||||
Mutant. | |||||
</p> | |||||
<p> | |||||
The first section identifies a set of issues with Ant1 that have cropped up as | |||||
Ant1 has evolved. The design implications of each issue are then summarized as a | |||||
Mutant requirement. I do not want to suggest that these problems are unsolvable | |||||
within the Ant1 design. Already I believe we have seen the Ant2 proposals | |||||
influencing people trying to extend Ant1. These issues may be solvable, although at | |||||
the risk of backward compatability impacts or further complication of the Ant1 | |||||
codebase. | |||||
</p> | |||||
<p> | |||||
The second section covers a set of additional requirements that have emerged as | |||||
the whole concept of Ant2 has developed. Many of these came from the discussions | |||||
on the Ant-Dev mailing list. | |||||
</p> | |||||
<p> | |||||
The realisation of these requirements as they impact a user is on the | |||||
<a href="features.html">next page</a>. Th implications for task developers and | |||||
Ant developers are discussed in the following sections. | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Ant1 Issues"><strong>Ant1 Issues</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Unrestricted core access"><strong>Unrestricted core access</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
The interface between the Ant core and tasks is not controlled. It | |||||
allows tasks almost complete access to the internal data structures of the | |||||
core. This is poor encapsulation. Whilst most tasks do not need and do not | |||||
use this access, its existence nonetheless prevents changes being made to | |||||
the core without raising concerns about impacting backward compatability. | |||||
</p> | |||||
<p> | |||||
The uncontrolled nature of the task-core interface also makes it difficult | |||||
to reuse tasks and types in a different context without almost completely | |||||
duplicating the Ant core | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
A tightly defined interface between the core and the components (tasks and | |||||
types) will allow the core implementation to be changed without the risk | |||||
of impacting tasks. It will also allow components to be reused in other | |||||
contexts. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Lack of embedding support"><strong>Lack of embedding support</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
Ant1 does not provide strong support for embedding Ant in other systems, | |||||
particularly a GUI or IDE. The development of Antidote highlighted this | |||||
difficultly. Antidote was forced to perform its own XML parsing so it could | |||||
build its own model of the build. There is no communication medium for a GUI to | |||||
communicate with the core. Without this capability any GUI will be limited to | |||||
simply editing the XML representation of the build. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
The definition of a project model, a Java-based object-model of a build | |||||
description would decouple Ant from the XML representation. This allows | |||||
other representations to be used. Such an object model also forms the basis | |||||
for communications between systems which want to embed Ant. An IDE could | |||||
manipulate this project object model directly and pass to the core for | |||||
processing without needing to convert to and from an external | |||||
representations such as XML. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Configuration done at Parse-Time"><strong>Configuration done at Parse-Time</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
The original implementation of Ant1 performed all task configuration at the | |||||
time the XML description of the build was parsed (parse-time). This approach | |||||
could not handle dynamically created tasks very well since in some | |||||
instances the type of the task to be configured was not known at parse-time. | |||||
This limitation was overcome with the introduction of the UnknownElement and | |||||
RuntimeConfigurable classes. While these work well, they are confusing and at | |||||
times surprising to most Ant developers. Also some operations still occur at | |||||
parse-time, notably creation of nested elements of known types. This could be | |||||
overcome by going to a fully dynamic model but the fear of backward | |||||
incompatability constrains this change from occuring. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Execution-time configuration of tasks allows for the latest information to be | |||||
used for configuration. It is also necessary to support the concept of the | |||||
project model. The project model cannot contain execution-time information as it | |||||
does in Ant1 | |||||
</p> | |||||
<p> | |||||
The decoupling of the parsing and exection phases, communicating through the | |||||
medium of the project model will allow the core to be modularized. The parsing | |||||
and execution phases can be separated and one replaced without impacting the | |||||
other. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Multiple execution"><strong>Multiple execution</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1, a task, once configured, may be used more than once - i.e. its | |||||
execute method may be called more than once. This occurs when the Ant | |||||
command line specifies the evaluation of two targets. If those targets have | |||||
overlapping dependencies, the tasks in those overlapping dependencies will | |||||
be executed twice. This arrangement requires task writers to preserve the | |||||
state configured by Ant during the execution of the task so that the next | |||||
execution has the correct configuration. | |||||
</p> | |||||
<p> | |||||
Many task writers are not aware of this requirement. Frequently the task's | |||||
state is changed during the execution method, which can lead to mysterious | |||||
falures during subsequent executions. This need to preserve the configuration | |||||
state makes writing tasks much harder. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Once a task is configured, it should be executed once. If the execution of | |||||
multiple targets is required, a new task instance should be created and | |||||
configured from the same project model. If reuse of task instances is desired | |||||
each instance must be reinitialized and reconfigured before use. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="No automatic deployment of tasks"><strong>No automatic deployment of tasks</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
Ant1 has a set of well-known tasks (and types). A well-known task is one | |||||
for which a mapping between the taskname and its implementing class is | |||||
predefined in Ant. This mapping is provided by the two defaults.properties | |||||
files in Ant's code. These well-known tasks do not need to be taskdef'd to | |||||
make them available in a build file. Conversely tasks which are not in this | |||||
list need to be explicitly taskdef'd. | |||||
</p> | |||||
<p> | |||||
Note that this distinction is not the same as the core/optional | |||||
distinction found in Ant1. An Ant1 core task is notionally supported by Ant | |||||
without requiring any additional external libraries - it just requires the | |||||
classes available in the 1.1 JDK, in Ant and in the libraries Ant uses such | |||||
as the XML parser. An optional task is a task which requires JDK 1.2+ | |||||
features or the support of an external library, such as jakarta-regexp. | |||||
</p> | |||||
<p> | |||||
The problem with this system is that there is no namespace management. If a | |||||
new task is added to Ant, it may invalidate buildfiles which are already | |||||
using that taskname via a taskdef. Actually the taskdef may continue to work or | |||||
it may not - it will depend on the nested elements that the task definitions | |||||
support (see above discussion of regarding cofiguration at parse-time) | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Tasks need to be deployed in libraries by either placing them in well known | |||||
directories of an Ant install or by telling Ant where to look for them. Removing | |||||
the central management of defined task names allows tasks libraries to be | |||||
developed and maintained independently of Ant much more easily. | |||||
</p> | |||||
<p> | |||||
Once centralised management of the task namespace is removed, there is, | |||||
however, the possibility of name collision. A mechanism is required to allow a | |||||
build file writer to select which particular tasks are assigned to which | |||||
tasknames. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Top level tasks"><strong>Top level tasks</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1 certain tasks may appear outside of any target. This is implemented as a | |||||
set of hardcoded conditions in the XML parsing phase. The execution and | |||||
configuration of these tasks does not involve the use of RuntimeConfigurable and | |||||
UnknownElement. | |||||
</p> | |||||
<p> | |||||
This hardcoding is not very inituitive. It is confusing to users who do not | |||||
know why only some tasks may be run outside of a target. Also as the list of | |||||
tasks that may be useful as a top-level task grows, further special cases must | |||||
be added to the code making the code harder to maintain. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
The number of special names should be kept to a minimum. Special cases should | |||||
be avoided as they are not inituitive. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Build file inclusion is cumbersome"><strong>Build file inclusion is cumbersome</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1, the inclusion of a set of build file definitions or targets is achieved | |||||
through the use of XML entities. This is just cumbersome. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
A simplified include mechanism is required to replace the entity based | |||||
inclusion of Ant1. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Classpath management"><strong>Classpath management</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
Probably the greatest issue facing Ant1 today involves the management of the | |||||
classpath and the associated visibility of classes. Most optional tasks in Ant1 | |||||
require the supporting classes for the task to be available on the system | |||||
classpath. For example, the JUnit task is only usable if the JUnit jar is on | |||||
the classpath. If it is not, Ant will complain about being unable to create the | |||||
junit task. | |||||
</p> | |||||
<p> | |||||
The usual solution when a user runs into this problem is to put the required jar | |||||
into the ANT_HOME/lib directory. This just adds the required jar to the system | |||||
classpath prior to starting Ant albeit without requiring the user to explicitly | |||||
set the classpath. | |||||
</p> | |||||
<p> | |||||
There are a number of issues with this approach. The classes on the | |||||
classpath share the same classloader as Ant's classes and Ant's support | |||||
libraries - particularly the XML parser. If a task wishes to use a specific XML | |||||
parser, it may conflict with Ant's own parser. If two tasks require different | |||||
versions of a supporting jar, these will conflict. | |||||
</p> | |||||
<p> | |||||
Many tasks make use of factory objects (dynamic class instantiation, dynamic | |||||
resource loading, etc). When the factory is in the system classpath it will not | |||||
be able to load resources available in a taskdef'd task's custom classpath due | |||||
to the delegating nature of classloaders. Such errors can be very confusing to | |||||
users. More recent code is likely to attempt use of a context classloader but | |||||
this is not set by Ant1 currently. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Do not require jars to be added to ANT_HOME/lib to enable tasks. Allow users to | |||||
specify the location of support jars on a per-library basis. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Extensibility"><strong>Extensibility</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
The earliest versions Ant1 did not explicitly support any datatypes. The only | |||||
datatype, property, was actually created as a side-effect of running the | |||||
<code><property></code> task. If it were to be implemented today, property | |||||
would probably be known as a string datatype, perhaps associated with a | |||||
<code><load-properties></code> task. This is also the reason property | |||||
is one of those tasks which is allowed to exist outside of a target. | |||||
</p> | |||||
<p> As Ant1 evolved new types such as <code><path></code> and | |||||
<code><fileset></code> were added. The concept of datatypes has continued | |||||
to evolve to the point where users can now define new datatypes. It would be | |||||
expected that in addition to new types there will be many sub-types created, | |||||
such as new types of fileset. Ant1, however, does not strongly support such type | |||||
extensibility. When a subtype is created by extending an existing type, Ant1 | |||||
requires it to be either used by reference or all tasks which accept the base | |||||
type need to be modified to support the new type. Use by reference is not always | |||||
possible. It will depend on whether the base type has been coded to support | |||||
references. </p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Support polymorphic behaviour, allowing a build file to pass a subtype to a | |||||
task which is defined to accept the base type. Allow task interfaces to be | |||||
defined in terms of interfaces. | |||||
</p> | |||||
<p> | |||||
Move reference processing to the core to make it more regular removing the | |||||
burden of type developers to explicitly support references. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Project object does too much"><strong>Project object does too much</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1 the Project object takes on too many roles including all of the | |||||
following: | |||||
</p> | |||||
<ul> | |||||
<li>Holds the project model built when parsing the build file</li> | |||||
<li>Holds the run-time state of the build through the properties and current | |||||
task definitions</li> | |||||
<li>Provides context for task execution. All tasks have a reference to their | |||||
project instance and use it to access core functions</li> | |||||
<li>Provides the implementation of common task operations</li> | |||||
<li>Build event management</li> | |||||
<li>Message logging</li> | |||||
<li>Global filter definitions</li> | |||||
<li>Java Version</li> | |||||
<li>Property replacement</li> | |||||
<li>Message Levels</li> | |||||
<li>Utility functions such as boolean conversion and path translation</li> | |||||
<li>Integration point for embedding Ant</li> | |||||
</ul> | |||||
<p> As a class, Project is not cohesive. Reuse of the Ant core functionality is | |||||
difficulty as all of these concerns bring in many other support classes. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Separate the various roles of Project into more cohesive classes. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Other Goals"><strong>Other Goals</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In addition to the issues which arise from Ant1 limitations, there are a number | |||||
of requirements which have emerged in the mailing list discussions about Ant2. | |||||
This isn't a complete list - just the ones I picked up for Mutant. | |||||
</p> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Limited project reuse"><strong>Limited project reuse</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> In Ant1 the only way to reuse build file definitions is to use the | |||||
<code><ant></code> task. While useful, it is relatively coarse-grained. It | |||||
can also be tedious if you are trying to extend an existing project definition - | |||||
that is, adding new targets while retaining a user's ability to access the | |||||
existing targets. </p> | |||||
<p> | |||||
In addition to the extension of projects, it should be possible to compose | |||||
projects creating dependencies between the targets of the different projects, | |||||
and to access the data and definitions of one project by a controlling project | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Allow a project to extend and control other projects | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Ant1 Compatibility - Zero Friction"><strong>Ant1 Compatibility - Zero Friction</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
While it has always been accepted that there will be come backward compatibility | |||||
breaks in moving from Ant1 to Ant2, these should be minimized. If the changeover | |||||
from Ant1 to Ant2 is difficult, it may never happen. On the other hand, the | |||||
openness of the Ant1 interface means that some tasks will not work as expected - | |||||
the most difficult being the <code><script></code> task. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Achieve a practical level of compatability without degrading the integrity of | |||||
the core's interfaces. A practical level of compatability is intentionally a | |||||
vague measure but it would require the majority of projects in Gump to be built | |||||
without noticeable differences from Ant1 | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="XML Configuration"><strong>XML Configuration</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1 configuration of Ant is achieved either through the execution of OS | |||||
dependent scripts by the launcher scripts or though properties files which have | |||||
the limited capability to set properties. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Provide an XML based configuration system with rich capabilities to configure | |||||
the operation of Ant. | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#828DA6"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Aspects"><strong>Aspects</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
In Ant1 there are many things which are common to a group of tasks but adding | |||||
the capability to each task is repetitive and tedious. An example would be the | |||||
failonerror attribute which controls whether a task will cause the build to stop | |||||
when it fails. This started on just one task but has since been added to many | |||||
other tasks as users want more fine control over when their builds stop. Aspects | |||||
have been discussed as a mechanism for providing a single implementation of a | |||||
concept or control that can then be applied to tasks independently. | |||||
</p> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<p> | |||||
Investigate the use of an Aspect approach to provide common functionality | |||||
across tasks with a single implementation | |||||
</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<!-- FOOTER --> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr><td colspan="2"> | |||||
<div align="center"><font color="#525D76" size="-1"><em> | |||||
Copyright © 2002, Apache Software Foundation | |||||
</em></font></div> | |||||
</td></tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
<!-- end the processing --> | |||||
@@ -0,0 +1,180 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
<!-- Content Stylesheet for Site --> | |||||
<!-- start the processing --> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |||||
<meta name="author" value="Conor MacNeill"> | |||||
<meta name="email" value=""> | |||||
<title>Mutant Proposal - Mutant Introduction</title> | |||||
</head> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | |||||
<!-- TOP IMAGE --> | |||||
<tr> | |||||
<td colspan="2"> | |||||
<a href="http://jakarta.apache.org"><img src="http://jakarta.apache.org/images/jakarta-logo.gif" align="left" border="0"/></a> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
<table border="0" width="100%" cellspacing="4"> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr> | |||||
<!-- LEFT SIDE NAVIGATION --> | |||||
<td valign="top" nowrap="true"> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | |||||
<li> <a href="./index.html">Introduction</a> | |||||
</li> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | |||||
<li> <a href="./features.html">User Features</a> | |||||
</li> | |||||
<li> <a href="./developers.html">Task Developers</a> | |||||
</li> | |||||
<li> <a href="./design.html">Design Description</a> | |||||
</li> | |||||
</ul> | |||||
</td> | |||||
<td align="left" valign="top"> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Introduction"><strong>Introduction</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
These pages describe the design and implementation of Mutant. | |||||
</p> | |||||
<p> | |||||
For some time, there has been the concept of Ant 2.0. a rearchitecting of | |||||
Ant designed to address the shortcomings in the design of Ant 1.x, while | |||||
drawing the experience gained in that development. This rearchitecting | |||||
would most likely be accompanied by at least some break in backward | |||||
compatability. Over time Ant 2.0 has come to be known as Ant2 and the current | |||||
Ant codebase is generally known as Ant1. | |||||
</p> | |||||
<p> | |||||
Mutant is my proposal, a revolution, for Ant2. Actually, I consider it more | |||||
an evolution of the design and implementation used for Ant1, but in Jakarta | |||||
parlance, being a separate codebase, it is termed a revolution. | |||||
</p> | |||||
<p> | |||||
There is no special significance in the name Mutant. I chose it because, as | |||||
a word, it is an extension of the word Ant and it also signifies a change | |||||
from the previous generation | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Other Proposals"><strong>Other Proposals</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
Mutant is not the only proposed revolution for Ant2. Peter Donald has | |||||
developed another known as | |||||
<a href="http://jakarta.apache.org/ant/myrmidon">Myrmidon</a> | |||||
which presents a different view of how Ant2 could be realized. Other | |||||
people hold the view that Ant1 can continue to evolve and that there | |||||
is no need for rearchitecture of its codebase. I recommend you | |||||
investigate all these points of view. | |||||
</p> | |||||
<p> | |||||
As I write this, no decision has been taken as to which codebase will be | |||||
adopted for Ant2. It may not be Mutant and it could even be some entirely | |||||
new proposal. These pages do not compare and contrast Mutant with these | |||||
other proposals or points of view, at least not explicitly. They are just | |||||
intended to describe how Mutant is designed and implemented and why it is the | |||||
way it is. | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Getting Started"><strong>Getting Started</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
<h1><font color="red">Caution</font></h1> | |||||
<p> | |||||
Mutant is not even an alpha release. While it is relatively stable, it is | |||||
subject to change. There are no backward compatability guarantees for any of | |||||
the classes, interfaces, build files, configuration, launch scripts, etc that | |||||
Mutant provides. | |||||
</p> | |||||
<p>In particular, some features in Mutant are experimental and may not, in the | |||||
long run, prove to be worthwhile.</p> | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
<p> | |||||
<a href="goals.html">Start</a> now by looking at the key requirements which have | |||||
shaped the design of Mutant. | |||||
</p> | |||||
<div align="right"> | |||||
<p>Conor MacNeill</p> | |||||
</div> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<!-- FOOTER --> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr><td colspan="2"> | |||||
<div align="center"><font color="#525D76" size="-1"><em> | |||||
Copyright © 2002, Apache Software Foundation | |||||
</em></font></div> | |||||
</td></tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
<!-- end the processing --> | |||||
@@ -0,0 +1,121 @@ | |||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | |||||
<!-- Content Stylesheet for Site --> | |||||
<!-- start the processing --> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | |||||
<meta name="author" value="Conor MacNeill"> | |||||
<meta name="email" value=""> | |||||
<title>Mutant Proposal - Mutant Introduction</title> | |||||
</head> | |||||
<body bgcolor="#ffffff" text="#000000" link="#525D76"> | |||||
<table border="0" width="100%" cellspacing="0"> | |||||
<!-- TOP IMAGE --> | |||||
<tr> | |||||
<td colspan="2"> | |||||
<a href="http://jakarta.apache.org"><img src="http://jakarta.apache.org/images/jakarta-logo.gif" align="left" border="0"/></a> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
<table border="0" width="100%" cellspacing="4"> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr> | |||||
<!-- LEFT SIDE NAVIGATION --> | |||||
<td valign="top" nowrap="true"> | |||||
<p><strong>Mutant Proposal</strong></p> | |||||
<ul> | |||||
<li> <a href="./intro.html">Introduction</a> | |||||
</li> | |||||
<li> <a href="./goals.html">Design Goals</a> | |||||
</li> | |||||
</ul> | |||||
</td> | |||||
<td align="left" valign="top"> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Introduction"><strong>Introduction</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
These pages describe the design and implementation of mutant. | |||||
</p> | |||||
<p> | |||||
For some time, there has been the concept of Ant 2.0. a rearchitecting of | |||||
Ant designed to address the shortcomings in the design of Ant 1.x while | |||||
drawing the experience gained in that development. This rearchitecting | |||||
would most likely be accompanied by at least some break in backward | |||||
compatability. Indeed this fact was recognized by Duncan, the original | |||||
author of Ant when he proposed his AntEater revolution. Over time Ant 2.0 | |||||
has come to be known as Ant2 and the current Ant codebase is generally | |||||
known as Ant1. | |||||
</p> | |||||
<p> | |||||
Mutant is my proposal, a revolution, for Ant2. Actually, I consider it more | |||||
an evolution of the design and implementation used for Ant1, but in Jakarta | |||||
parlance, being a separate codebase, it is termed a revolution. | |||||
</p> | |||||
<p> | |||||
There is no special significance in the name mutant. I chose it because, as | |||||
a word, it is an extension of the word ant and it also signifies a change | |||||
from the previos generation | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
<table border="0" cellspacing="0" cellpadding="2" width="100%"> | |||||
<tr><td bgcolor="#525D76"> | |||||
<font color="#ffffff" face="arial,helvetica,sanserif"> | |||||
<a name="Other Proposals"><strong>Other Proposals</strong></a> | |||||
</font> | |||||
</td></tr> | |||||
<tr><td> | |||||
<blockquote> | |||||
<p> | |||||
Mutant is not the only proposed revolution for Ant2. Peter Donald, another | |||||
Ant committer, has developed another proposal known as Myrmidon, which you | |||||
should also investigate if you are interested in a different view of how | |||||
Ant2 should be realized. Other people hold the view that there is no need | |||||
for any rearchitecting and the Ant1 codebase can continue to evolve. | |||||
</p> | |||||
<p> | |||||
As I write this, no decision has been taken as to which codebase will be | |||||
adopted for Ant2. It may not be mutant or it could be some entirely new | |||||
proposal. This document does not compare and contrast mutant with these | |||||
other proposals or points of view, at least not explicitly. It is just | |||||
intended to describe and highlight how mutant is designed and implemented. | |||||
</p> | |||||
</blockquote> | |||||
</td></tr> | |||||
</table> | |||||
</td> | |||||
</tr> | |||||
<!-- FOOTER --> | |||||
<tr><td colspan="2"> | |||||
<hr noshade="" size="1"/> | |||||
</td></tr> | |||||
<tr><td colspan="2"> | |||||
<div align="center"><font color="#525D76" size="-1"><em> | |||||
Copyright © 2000-2002, Apache Software Foundation | |||||
</em></font></div> | |||||
</td></tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
<!-- end the processing --> | |||||
@@ -0,0 +1,16 @@ | |||||
<document> | |||||
<properties> | |||||
<author email="">Conor MacNeill</author> | |||||
<title>Developers</title> | |||||
</properties> | |||||
<body> | |||||
<section name="Developers"> | |||||
<p> | |||||
This page will describe the design of Mutant's core. | |||||
</p> | |||||
</section> | |||||
</body> | |||||
</document> | |||||
@@ -0,0 +1,16 @@ | |||||
<document> | |||||
<properties> | |||||
<author email="">Conor MacNeill</author> | |||||
<title>Developers</title> | |||||
</properties> | |||||
<body> | |||||
<section name="Developers"> | |||||
<p> | |||||
This page will describe the operation of Mutant from a task developers perspective. | |||||
</p> | |||||
</section> | |||||
</body> | |||||
</document> | |||||
@@ -0,0 +1,599 @@ | |||||
<document> | |||||
<properties> | |||||
<author email="">Conor MacNeill</author> | |||||
<title>Mutant Features</title> | |||||
</properties> | |||||
<body> | |||||
<section name="User Features"> | |||||
<p> | |||||
This page describes the major features in Mutant which are significantly | |||||
different from those of Ant1. These are covered from a user perspective. Other | |||||
pages describe the differences from the perspectives of a task developer and an | |||||
Ant core developer. | |||||
</p> | |||||
</section> | |||||
<section name="Directory Layout"> | |||||
<p> | |||||
When Mutant is installed, the most immediately obvious difference will be in the | |||||
directory layout, particularly the lib directory. Where Ant1's lib directory | |||||
contained ant.jar, optional.jar and the bundled XML jars, Mutant's lib directory | |||||
contain a number of subdirectories. | |||||
</p> | |||||
<p> | |||||
In the root directory, there are a number of jars. These jars are the startup | |||||
jars | |||||
</p> | |||||
<table> | |||||
<tr> | |||||
<td>init.jar</td> | |||||
<td>a set of low level utility routines required at startup</td> | |||||
</tr> | |||||
<tr> | |||||
<td>start.jar</td> | |||||
<td>the Mutant launcher class</td> | |||||
</tr> | |||||
<tr> | |||||
<td>ant.jar</td> | |||||
<td>old Ant1 entry point</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
The subdirectories have the following functions | |||||
</p> | |||||
<table> | |||||
<tr> | |||||
<td>parser</td> | |||||
<td>The XML parser jars. This is not available to task libraries unless | |||||
they explicitly indicate that it is required.</td> | |||||
</tr> | |||||
<tr> | |||||
<td>antcore</td> | |||||
<td>Mutant's core classes. These classes are not available to | |||||
tasks.</td> | |||||
</tr> | |||||
<tr> | |||||
<td>common</td> | |||||
<td>classes which are available to both the core and all task | |||||
libraries.</td> | |||||
</tr> | |||||
<tr> | |||||
<td>syslibs/antlibs</td> | |||||
<td>Task libraries. The distinction between the two is | |||||
discussed below.</td> | |||||
</tr> | |||||
<tr> | |||||
<td>frontend</td> | |||||
<td>Ant Frontends. Different frontends may be plugged in by placing | |||||
jars here.</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
The directory a jar is in will control the visibility of the jar's classes and | |||||
resources. This is closely related to the classloader hiearchy used by | |||||
Mutant. | |||||
</p> | |||||
</section> | |||||
<section name="Ant Libraries"> | |||||
<p> | |||||
Mutant supports the concept of Ant Libraries. These are collections of | |||||
components (tasks and types) and their supporting classes packaged into a | |||||
Jar. In Mutant each library has a globally unique identifier. This identifier | |||||
uses the same conventions as Java package naming - i.e. a reverse DNS name. | |||||
</p> | |||||
<p> The jar does not need to be exclusively for Ant. For example, it may be the | |||||
jar for a tool which wishes to provide some Ant tasks for using the tool. It | |||||
could be the main jar of an appication server that bundles Ant tasks for | |||||
deployment. The jar does not even need to be installed in Mutant's antlib | |||||
directory - Mutant can be configured to look in jars in other locations for Ant | |||||
Libraries. </p> | |||||
<subsection name="Ant library descriptor"> | |||||
<p> | |||||
Whatever the jar contains and wherever it is located, Mutant looks for an XML | |||||
based descriptor in the jar at META-INF/antlib.xml. This XML file describes the | |||||
components in the jar that will be available to Mutant. | |||||
</p> | |||||
<p> | |||||
Here is an example of the descriptor. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<antlib libid="ant.system" | |||||
home="http://jakarta.apache.org/ant"> | |||||
<taskdef name="libpath" classname="org.apache.ant.antlib.system.LibPath"/> | |||||
<taskdef name="loadlib" classname="org.apache.ant.antlib.system.LoadLib"/> | |||||
<taskdef name="import" classname="org.apache.ant.antlib.system.Import"/> | |||||
<converter classname="org.apache.ant.antlib.system.FileConverter"/> | |||||
<converter classname="org.apache.ant.antlib.system.URLConverter"/> | |||||
<converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/> | |||||
<aspect classname="org.apache.ant.antlib.system.AntAspect"/> | |||||
</antlib> | |||||
]]></source> | |||||
<p> | |||||
As a user you generally won't need to worry about this decriptor. The library | |||||
developer will have developed it to describe their library. Mutant uses the | |||||
descriptor to understand what Ant related components the library provides. | |||||
</p> | |||||
</subsection> | |||||
<subsection name="Loading libraries"> | |||||
<p> | |||||
Library management in Mutant is split into two phases - a loading phase and an | |||||
import phase. The loading phase is where Mutant loads the antlib.xml descriptor | |||||
from the library. After loading, Mutant knows where the library is located and | |||||
what components it provides. In general Mutant will not make the components | |||||
available to build scripts automatically. A build script needs to notify Mutant | |||||
what components it is using from each library. This is known as importing. | |||||
</p> | |||||
<p> Mutant loads libraries from two locations within the Mutant directory | |||||
structure when Mutant starts up - the lib/syslibs and lib/antlibs directories. | |||||
The distinction between these two locations is explained in the configuration | |||||
discussion below. All jars in these directories will be search for library | |||||
descriptors. All libraries providing descriptors will be available for importing | |||||
into builds</p> | |||||
<p> In addition to the automatically loaded libraries, it is possible to | |||||
explicitly request additional libraries to be loaded using the | |||||
<code><loadlib></code> task. Individual libraries may be loaded or a set | |||||
of libraries loaded from a directory. Libraries may also be loaded from remote | |||||
locations by specifying a URL. The loadlib task can request that all components | |||||
in the loaded library also be imported at the time of loading. Examples of the | |||||
loadlib task follow </p> | |||||
<source><![CDATA[ | |||||
<!-- load a library from a specific file and import all components --> | |||||
<loadlib file="/opt/tools/toollib.jar" importall="true"/> | |||||
<!-- load all libraries from a directory --> | |||||
<loadlib dir="/opt/appserver/lib/"/> | |||||
<!-- load libraries from a remote server --> | |||||
<loadlib url="http://jakarta.apache.org/ant/testtasks.jar"/> | |||||
]]></source> | |||||
<p> | |||||
In general the loading of libraries from absolute locations would be a | |||||
configuration task. These would be specified in the Mutant configuration file | |||||
and would not be used in a build file. The loading of project libraries from | |||||
relative locations may be something that you would see in a build file. | |||||
</p> | |||||
</subsection> | |||||
<subsection name="Importing components"> | |||||
<p> | |||||
Mutant is designed to allow tasks to be defined simply by dropping a jar in a | |||||
directory or configuring Mutant to look in particular places for jars. This will | |||||
allow tasks and types developed by many different developers to be used. With | |||||
many developers developing tasks, however, inevitably some tasks will end up | |||||
with the same name. | |||||
</p> | |||||
<p> | |||||
This is very similar to the situation faced by Java with Java class names. | |||||
Many Java classes have the same name. When a Java programmer uses a class they | |||||
must import that class with an import statement. This tells the Java compiler | |||||
which particular class is being referenced by the classname. Effectively the | |||||
import statement creates a mapping from a name used in the Java source file and | |||||
a class in the global package namespace. | |||||
</p> | |||||
<p> | |||||
Mutant provides an import task to specify, in a manner similar to Java's import | |||||
statement, which components are being used. When a component is imported the | |||||
library is identified by its unique id. By default the component is imported | |||||
into the frame using the name it is known by within the library. When this would | |||||
conflict with a name that has already been imported, the import task allows the | |||||
component to be given a new name, or alias, by which it will be referenced. It | |||||
is also possible to import all the components in a library. The folowing example | |||||
shows the various methods by which the import task can be used to import | |||||
components. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<!-- import the runtool task from the com.foo.tools library --> | |||||
<import libraryId="com.foo.tools" name="runtool"/> | |||||
<!-- import the runtool task from the com.bar.tools library and | |||||
alias it since the runtool is already defined --> | |||||
<import libraryId="com.bar.tools" name="runtool" alias="runbartool"/> | |||||
<!-- import all of the tasks from the com.fubar.tools library --> | |||||
<import libraryId="com.fubar.tools"/> | |||||
]]></source> | |||||
<p> | |||||
By using library identifiers, import operations are not tied to a particular | |||||
library location. The separation of the loading and importing into separate | |||||
phases allows environment-dependent locations to be specified as configuration | |||||
information and location independent importing to be specified in the build | |||||
file. This is similar to the case of Java imports. Java classes are imported by | |||||
their global name without needing to known where the classfile is that contains | |||||
that class. That information is provided externally in the CLASSPATH variable. | |||||
</p> | |||||
</subsection> | |||||
<subsection name="Library classpath management"> | |||||
<p> | |||||
Many libraries will have dependencies on external jars. For example, a task | |||||
might make use of regular-expression libraries such as jakarta-regexp or a task | |||||
may provide a wrapper around some external tool. In these cases the task will | |||||
usually need to have the required classes available in the classloader from | |||||
which the task itself was loaded. It is possible to avoid these direct | |||||
dependencies using techniques such as reflection and explicitly loading the | |||||
required classes through additional classloaders but the code is often harder to | |||||
write and understand. | |||||
</p> | |||||
<p> It is not always possible or desirable to bundle the required classes in the | |||||
task's jar nor is it desirable that the system classpath contains the required | |||||
classes. In fact it is often preferable to run Mutant with an empty classpath. | |||||
Buildfiles which do not assume that the system classpath contains particular | |||||
classes are generally more portable. Mutant provides a task, | |||||
<code><libpath></code>, to allow additional paths to be assodicated with a | |||||
library. As with the loadlib task, the libpath task may be used to associate a | |||||
single file, all jars in a directory or remote jars with a library. </p> | |||||
<source><![CDATA[ | |||||
<libpath libraryid="ant.ant1compat" | |||||
dir="/home/conor/jakarta-ant/lib/optional/"/> | |||||
]]></source> | |||||
<p> The above example associates all the jars in | |||||
/home/conor/jakarta-ant/lib/optional/ with the library whose unique id is | |||||
ant.ant1compat. A path must be associated with a library before any components | |||||
are imported from the library. Mutant associates the paths with the library and | |||||
at the time a component is requested from the library, Mutant will form the | |||||
classloader that will be used. The additional paths are added to the definition | |||||
of the classloader. Once a component is loaded, further paths will not have any | |||||
effect. For this reason, and since the additonal paths are likely to be absolute | |||||
paths, the <code><libpath></code> task is normally used in Mutant's | |||||
configuration phase. </p> | |||||
</subsection> | |||||
<subsection name="Automatic Imports"> | |||||
<p> | |||||
Mutant will automatically import all components of any library whose unique | |||||
identifier begins with "ant." when the ;library is loaded. This is | |||||
mainly a convenience to provide a minimum set of tasks with which to construct | |||||
build files. | |||||
</p> | |||||
</subsection> | |||||
</section> | |||||
<section name="Includes"> | |||||
<p>Mutant provides a mechanism for including build file fragments into a build | |||||
file. This following example illustrates how this works</p> | |||||
<source><![CDATA[ | |||||
build.ant | |||||
========== | |||||
<project default="main" xmlns:ant="http://jakarta.apache.org/ant"> | |||||
<ant:include fragment="fragment.ant"/> | |||||
</project> | |||||
fragment.ant | |||||
============ | |||||
<fragment> | |||||
<target name="main"> | |||||
<echo message="main target"/> | |||||
</target> | |||||
</fragment> | |||||
]]></source> | |||||
<p> The include mechanism can be used to include a complete project file or as | |||||
shown in the example, a fragment. When including a project, any attributes on | |||||
the included <code><project></code> element are ignored and the contents | |||||
of the project inserted into the including project. In all cases the included | |||||
files must be a well formed XML file containing a root element. </p> | |||||
<box> | |||||
<p><font color="red">This area of Mutant is subject to change.</font></p> | |||||
<p>At present include elements are processed at parse-time. As such they can | |||||
only occur at the top-level of the build file. They cannot occur in a target. | |||||
The use of the namespace to qualify the include element is intended to convey | |||||
the fact that this is not part of the build structure.</p> | |||||
<p>An alternative approach would be to define include as a regular task. When an | |||||
include is processed, the top-level tasks of the included project would be | |||||
executed immediately and the targets added to the current project | |||||
structure.</p>. | |||||
</box> | |||||
</section> | |||||
<section name="Project References"> | |||||
<subsection name="Creating references"> | |||||
<p> | |||||
Mutant allows build file writers to reference properties and targets in other | |||||
projects by creating a project reference. Project references are introduced | |||||
using the ref task. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<!-- create a reference to the main build --> | |||||
<ref project="main.xml" name="main"/> | |||||
<ref project="test.xml" name="test"> | |||||
<property name=build.dir" value="build/test"/> | |||||
</ref> | |||||
]]></source> | |||||
<p> | |||||
The above example creates two project references - one to the build in main.xml | |||||
and one to the build in test.xml. When a reference is created, it must be given | |||||
a label. This label will be used to refer to items within the referenced | |||||
project (see below). Note that the ref task is a regular task and the reference | |||||
is only created when the ref task is executed. A ref task may be placed at the | |||||
top level of a build to effectively create static references. Alternatively a | |||||
reference may be created dynamically by putting the ref task in a target. | |||||
</p> | |||||
</subsection> | |||||
<subsection name="Referencing project items"> | |||||
<p> | |||||
The label given to a project reference is used when accessing items within the | |||||
project. So, to access the build.dir property in the project referenced by the | |||||
main label, you would use main:build.dir. Similarly the compile target would be | |||||
referred to as main:compile. Since the referenced projects may also create their | |||||
own project references, labels may be concatenated to access items at arbitrary | |||||
depths. For example, if main.xml referenced another project under the label | |||||
"sub", a property debug could be referenced as main:sub:debug. The | |||||
following example shows various items in the referenced project being used. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<!-- Specify the build.dir in the main project prior to the reference | |||||
being created --> | |||||
<property name="main:build.dir" value="build/main"/> | |||||
<!-- create the reference to the main build --> | |||||
<ref project="main.xml" name="main"/> | |||||
<!-- create the reference to the test build --> | |||||
<ref project="test.xml" name="test"> | |||||
<property name="build.dir" value="build/test"/> | |||||
</ref> | |||||
<!-- our main target calls the fubar target in the main build --> | |||||
<target name="main"> | |||||
<antcall target="main:fubar"/> | |||||
</target> | |||||
<!-- Our alt target depends on the fubar target in the main build --> | |||||
<target name="alt" depends="main:fubar"> | |||||
<echo message="main's debug flag is ${main:debug}"/> | |||||
</target> | |||||
]]></source> | |||||
<p> | |||||
When a project is referenced, the top level tasks of the referenced project are | |||||
run to allow the project to initialize itself. Mutant allows the referring | |||||
build to set a property in a referenced project before the reference is | |||||
created. When the reference is eventually created these properties are set | |||||
before initialization occurs. In normal Ant fashion, these overriding | |||||
properties take precedence. In particular properties in the referenced projects | |||||
may be set from the command line as this example shows | |||||
</p> | |||||
<source> | |||||
mutant -Dmain:build.dir=temp | |||||
</source> | |||||
<p> | |||||
The example above shows a target in the referenced project being used as a | |||||
dependency and also as a target in an antcall. Since refs are dynamic, Mutant | |||||
will only evaluate such dependencies when required. If the alt target were | |||||
never to be run, the dependency on main:fubar would never be checked. | |||||
</p> | |||||
<p> | |||||
The import task allows components defined in a referenced project to be brought | |||||
into the main build. For example, the following will bring the definition of | |||||
tool from the test project in the build. The imported component may also be | |||||
aliased to a new name. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<!-- import a task definition from another project --> | |||||
<import ref="test:tool"/> | |||||
]]></source> | |||||
</subsection> | |||||
</section> | |||||
<section name="Configuration"> | |||||
<p> | |||||
As discussed above Mutant provides a number of tasks to manage libraries and | |||||
it is appropriate to run many of these tasks as part of a user or system-wide | |||||
configuration rather than incorporating them into the build file. Mutant | |||||
provides a configuration system to support running these tasks at an appropriate | |||||
time. A Mutant configuration file looks as follows | |||||
</p> | |||||
<source><![CDATA[ | |||||
<antconfig allow-unset-properties="true"> | |||||
<global-tasks> | |||||
<libpath libraryid="ant.ant1compat" | |||||
file="/home/conor/dev/jakarta-ant/lib/optional/"/> | |||||
</global-tasks> | |||||
<project-tasks> | |||||
<import libraryid="antopt.monitor"/> | |||||
</project-tasks> | |||||
</antconfig> | |||||
]]></source> | |||||
<p> | |||||
The antconfig element is the root element of the configuration file. It supports | |||||
three attributes | |||||
</p> | |||||
<table> | |||||
<tr> | |||||
<td>allow-unset-properties</td> | |||||
<td>controls whether Mutant will fail a build which | |||||
refers to a property which has not been set. This defaults to the Ant1 behaviour | |||||
(true)</td> | |||||
</tr> | |||||
<tr> | |||||
<td>allow-remote-library</td> | |||||
<td>controls whether Mutant uses components defined in remote libraries</td> | |||||
</tr> | |||||
<tr> | |||||
<td>allow-remote-project</td> | |||||
<td>controls whether Mutant can run a project or reference a project which is | |||||
located remotely.</td> | |||||
</tr> | |||||
</table> | |||||
<p> | |||||
The configuration provides two collections of configuration tasks, global-tasks | |||||
and project-tasks. Global-tasks are run once and are run in the context of the | |||||
main project - i.e. the build file identified on the command line (defaults to | |||||
build.xml/build.ant), whilst project-tasks are run as part of the initialization | |||||
of every project including referenced projects and antcall projects. Looking at | |||||
the above example, the global-tasks associate a path with the ant.ant1compat | |||||
library while the per-project tasks import the antopt.monitor library into every | |||||
project that Mutant processes. | |||||
</p> | |||||
<p> | |||||
The tasks that can be run in the configuration phase are regular tasks but not | |||||
all tasks are automatically available. This is the difference between the | |||||
syslibs and antlibs directories. The global tasks are run after the syslibs | |||||
libraries have been loaded but prior to the antlibs libraries being loaded. The | |||||
syslibs library tasks are therefore available in the configuration phase. This | |||||
arrangement is to allow the configuration tasks to setup library paths for the | |||||
libraries contained in the antlibs directory, especially libraries in the Ant | |||||
namespace which are automatically imported at the time they are loaded. | |||||
</p> | |||||
<p> | |||||
If it is required to use tasks from libraries installed in the antlibs | |||||
directory, the configuration tasks may explicitly load the library and import | |||||
the required tasks. The following example shows the loading and use of the echo | |||||
task in the configuration tasks. Note that the ant.home property has been set at | |||||
the time the configuration tasks are started. | |||||
</p> | |||||
<source><![CDATA[ | |||||
<antconfig allow-unset-properties="true"> | |||||
<global-tasks> | |||||
<loadlib file="${ant.home}/lib/antlibs/ant1compat.jar" importall="true"/> | |||||
<echo message="Starting the build"/> | |||||
</global-tasks> | |||||
<project-tasks> | |||||
<echo message="Starting new project"/> | |||||
</project-tasks> | |||||
</antconfig> | |||||
]]></source> | |||||
<p> | |||||
When Mutant starts up it will load configurations from two locations - The file | |||||
.ant/conf/antconfig.xml in the user's home directory and the file | |||||
conf/antconfig.xml in the Mutant home directory. In addition, config files can | |||||
be specified on the command line using a -config argument. This allows project | |||||
specific configurations to be used. | |||||
</p> | |||||
</section> | |||||
<section name="Targetless builds"> | |||||
<p> | |||||
Mutant allows any task or datatype to be placed outside of a target. All such | |||||
components are processed when the project is initialized and before any targets | |||||
are processed. In fact Mutant does not require that a project contain any | |||||
targets. In this case the only operations performed are the top level tasks at | |||||
project initialization. The following shows a simple example | |||||
</p> | |||||
<source><![CDATA[ | |||||
<project> | |||||
<echo message="Welcome to Mutant"/> | |||||
</project> | |||||
]]></source> | |||||
</section> | |||||
<section name="Extensibility"> | |||||
<p> | |||||
Normally when a task supports a nested element, Ant automatically determines the | |||||
type of the nested element and creates an instance of this type. This instance is | |||||
then configured and passed to the task. Mutant extends this scheme by allowing | |||||
a build file writer to specify the type of nested element to use rather than | |||||
relying on the core to determine it. Mutant will process attributes and further | |||||
nested elements based on the specified type. For example: | |||||
</p> | |||||
<source><![CDATA[ | |||||
<copy todir="dest"> | |||||
<fileset xsi:type="classfileset" dir="../../bin/ant1compat/"> | |||||
<root classname="org.apache.tools.ant.Project"/> | |||||
</fileset> | |||||
</copy> | |||||
]]></source> | |||||
<p> | |||||
In this example the nested element is actually a classfileset which supports the | |||||
<root> nested element. The actual type is specified using the notation from | |||||
XML Schema. Mutant predclares the XML Schema namespace under the xsi prefix. You | |||||
may explicitly declare this in the build file's XML and use a different prefix | |||||
if you wish. For example, this is equivalent to the above | |||||
</p> | |||||
<source><![CDATA[ | |||||
<?xml version="1.0"?> | |||||
<project xmlns:schema="http://www.w3.org/2001/XMLSchema-instance" | |||||
name="test" default="main"> | |||||
<target name="main"> | |||||
<delete dir="dest"/> | |||||
<mkdir dir="dest"/> | |||||
<copy todir="dest"> | |||||
<fileset schema:type="classfileset" dir="../../bin/ant1compat/"> | |||||
<root classname="org.apache.tools.ant.Project"/> | |||||
</fileset> | |||||
</copy> | |||||
</target> | |||||
</project> | |||||
]]></source> | |||||
</section> | |||||
<section name="Default build file"> | |||||
<p>In Ant1, the default build file name is build.xml. In Mutant, the default | |||||
build file is build.ant. If build.xnt cannot be found, Mutant will then look for | |||||
build.xml. This allows you to support both Ant1 and Ant2 users. The build.xml | |||||
file can contain an Ant1 build file. The build.ant file can include or reference | |||||
this build and make use of Mutant's capabilities such as library management, | |||||
library path settings, etc. | |||||
</p> | |||||
</section> | |||||
</body> | |||||
</document> |
@@ -0,0 +1,426 @@ | |||||
<document> | |||||
<properties> | |||||
<author email="">Conor MacNeill</author> | |||||
<title>Mutant Goals</title> | |||||
</properties> | |||||
<body> | |||||
<section name="Goals"> | |||||
<p> | |||||
This page describes the key goals that have shaped the development of | |||||
Mutant. | |||||
</p> | |||||
<p> | |||||
The first section identifies a set of issues with Ant1 that have cropped up as | |||||
Ant1 has evolved. The design implications of each issue are then summarized as a | |||||
Mutant requirement. I do not want to suggest that these problems are unsolvable | |||||
within the Ant1 design. Already I believe we have seen the Ant2 proposals | |||||
influencing people trying to extend Ant1. These issues may be solvable, although at | |||||
the risk of backward compatability impacts or further complication of the Ant1 | |||||
codebase. | |||||
</p> | |||||
<p> | |||||
The second section covers a set of additional requirements that have emerged as | |||||
the whole concept of Ant2 has developed. Many of these came from the discussions | |||||
on the Ant-Dev mailing list. | |||||
</p> | |||||
<p> | |||||
The realisation of these requirements as they impact a user is on the | |||||
<a href="features.html">next page</a>. Th implications for task developers and | |||||
Ant developers are discussed in the following sections. | |||||
</p> | |||||
</section> | |||||
<section name="Ant1 Issues"> | |||||
<subsection name="Unrestricted core access"> | |||||
<p> | |||||
The interface between the Ant core and tasks is not controlled. It | |||||
allows tasks almost complete access to the internal data structures of the | |||||
core. This is poor encapsulation. Whilst most tasks do not need and do not | |||||
use this access, its existence nonetheless prevents changes being made to | |||||
the core without raising concerns about impacting backward compatability. | |||||
</p> | |||||
<p> | |||||
The uncontrolled nature of the task-core interface also makes it difficult | |||||
to reuse tasks and types in a different context without almost completely | |||||
duplicating the Ant core | |||||
</p> | |||||
<box> | |||||
<p> | |||||
A tightly defined interface between the core and the components (tasks and | |||||
types) will allow the core implementation to be changed without the risk | |||||
of impacting tasks. It will also allow components to be reused in other | |||||
contexts. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Lack of embedding support"> | |||||
<p> | |||||
Ant1 does not provide strong support for embedding Ant in other systems, | |||||
particularly a GUI or IDE. The development of Antidote highlighted this | |||||
difficultly. Antidote was forced to perform its own XML parsing so it could | |||||
build its own model of the build. There is no communication medium for a GUI to | |||||
communicate with the core. Without this capability any GUI will be limited to | |||||
simply editing the XML representation of the build. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
The definition of a project model, a Java-based object-model of a build | |||||
description would decouple Ant from the XML representation. This allows | |||||
other representations to be used. Such an object model also forms the basis | |||||
for communications between systems which want to embed Ant. An IDE could | |||||
manipulate this project object model directly and pass to the core for | |||||
processing without needing to convert to and from an external | |||||
representations such as XML. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Configuration done at Parse-Time"> | |||||
<p> | |||||
The original implementation of Ant1 performed all task configuration at the | |||||
time the XML description of the build was parsed (parse-time). This approach | |||||
could not handle dynamically created tasks very well since in some | |||||
instances the type of the task to be configured was not known at parse-time. | |||||
This limitation was overcome with the introduction of the UnknownElement and | |||||
RuntimeConfigurable classes. While these work well, they are confusing and at | |||||
times surprising to most Ant developers. Also some operations still occur at | |||||
parse-time, notably creation of nested elements of known types. This could be | |||||
overcome by going to a fully dynamic model but the fear of backward | |||||
incompatability constrains this change from occuring. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Execution-time configuration of tasks allows for the latest information to be | |||||
used for configuration. It is also necessary to support the concept of the | |||||
project model. The project model cannot contain execution-time information as it | |||||
does in Ant1 | |||||
</p> | |||||
<p> | |||||
The decoupling of the parsing and exection phases, communicating through the | |||||
medium of the project model will allow the core to be modularized. The parsing | |||||
and execution phases can be separated and one replaced without impacting the | |||||
other. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Multiple execution"> | |||||
<p> | |||||
In Ant1, a task, once configured, may be used more than once - i.e. its | |||||
execute method may be called more than once. This occurs when the Ant | |||||
command line specifies the evaluation of two targets. If those targets have | |||||
overlapping dependencies, the tasks in those overlapping dependencies will | |||||
be executed twice. This arrangement requires task writers to preserve the | |||||
state configured by Ant during the execution of the task so that the next | |||||
execution has the correct configuration. | |||||
</p> | |||||
<p> | |||||
Many task writers are not aware of this requirement. Frequently the task's | |||||
state is changed during the execution method, which can lead to mysterious | |||||
falures during subsequent executions. This need to preserve the configuration | |||||
state makes writing tasks much harder. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Once a task is configured, it should be executed once. If the execution of | |||||
multiple targets is required, a new task instance should be created and | |||||
configured from the same project model. If reuse of task instances is desired | |||||
each instance must be reinitialized and reconfigured before use. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="No automatic deployment of tasks"> | |||||
<p> | |||||
Ant1 has a set of well-known tasks (and types). A well-known task is one | |||||
for which a mapping between the taskname and its implementing class is | |||||
predefined in Ant. This mapping is provided by the two defaults.properties | |||||
files in Ant's code. These well-known tasks do not need to be taskdef'd to | |||||
make them available in a build file. Conversely tasks which are not in this | |||||
list need to be explicitly taskdef'd. | |||||
</p> | |||||
<p> | |||||
Note that this distinction is not the same as the core/optional | |||||
distinction found in Ant1. An Ant1 core task is notionally supported by Ant | |||||
without requiring any additional external libraries - it just requires the | |||||
classes available in the 1.1 JDK, in Ant and in the libraries Ant uses such | |||||
as the XML parser. An optional task is a task which requires JDK 1.2+ | |||||
features or the support of an external library, such as jakarta-regexp. | |||||
</p> | |||||
<p> | |||||
The problem with this system is that there is no namespace management. If a | |||||
new task is added to Ant, it may invalidate buildfiles which are already | |||||
using that taskname via a taskdef. Actually the taskdef may continue to work or | |||||
it may not - it will depend on the nested elements that the task definitions | |||||
support (see above discussion of regarding cofiguration at parse-time) | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Tasks need to be deployed in libraries by either placing them in well known | |||||
directories of an Ant install or by telling Ant where to look for them. Removing | |||||
the central management of defined task names allows tasks libraries to be | |||||
developed and maintained independently of Ant much more easily. | |||||
</p> | |||||
<p> | |||||
Once centralised management of the task namespace is removed, there is, | |||||
however, the possibility of name collision. A mechanism is required to allow a | |||||
build file writer to select which particular tasks are assigned to which | |||||
tasknames. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Top level tasks"> | |||||
<p> | |||||
In Ant1 certain tasks may appear outside of any target. This is implemented as a | |||||
set of hardcoded conditions in the XML parsing phase. The execution and | |||||
configuration of these tasks does not involve the use of RuntimeConfigurable and | |||||
UnknownElement. | |||||
</p> | |||||
<p> | |||||
This hardcoding is not very inituitive. It is confusing to users who do not | |||||
know why only some tasks may be run outside of a target. Also as the list of | |||||
tasks that may be useful as a top-level task grows, further special cases must | |||||
be added to the code making the code harder to maintain. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
The number of special names should be kept to a minimum. Special cases should | |||||
be avoided as they are not inituitive. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Build file inclusion is cumbersome"> | |||||
<p> | |||||
In Ant1, the inclusion of a set of build file definitions or targets is achieved | |||||
through the use of XML entities. This is just cumbersome. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
A simplified include mechanism is required to replace the entity based | |||||
inclusion of Ant1. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Classpath management"> | |||||
<p> | |||||
Probably the greatest issue facing Ant1 today involves the management of the | |||||
classpath and the associated visibility of classes. Most optional tasks in Ant1 | |||||
require the supporting classes for the task to be available on the system | |||||
classpath. For example, the JUnit task is only usable if the JUnit jar is on | |||||
the classpath. If it is not, Ant will complain about being unable to create the | |||||
junit task. | |||||
</p> | |||||
<p> | |||||
The usual solution when a user runs into this problem is to put the required jar | |||||
into the ANT_HOME/lib directory. This just adds the required jar to the system | |||||
classpath prior to starting Ant albeit without requiring the user to explicitly | |||||
set the classpath. | |||||
</p> | |||||
<p> | |||||
There are a number of issues with this approach. The classes on the | |||||
classpath share the same classloader as Ant's classes and Ant's support | |||||
libraries - particularly the XML parser. If a task wishes to use a specific XML | |||||
parser, it may conflict with Ant's own parser. If two tasks require different | |||||
versions of a supporting jar, these will conflict. | |||||
</p> | |||||
<p> | |||||
Many tasks make use of factory objects (dynamic class instantiation, dynamic | |||||
resource loading, etc). When the factory is in the system classpath it will not | |||||
be able to load resources available in a taskdef'd task's custom classpath due | |||||
to the delegating nature of classloaders. Such errors can be very confusing to | |||||
users. More recent code is likely to attempt use of a context classloader but | |||||
this is not set by Ant1 currently. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Do not require jars to be added to ANT_HOME/lib to enable tasks. Allow users to | |||||
specify the location of support jars on a per-library basis. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Extensibility"> | |||||
<p> | |||||
The earliest versions Ant1 did not explicitly support any datatypes. The only | |||||
datatype, property, was actually created as a side-effect of running the | |||||
<code><property></code> task. If it were to be implemented today, property | |||||
would probably be known as a string datatype, perhaps associated with a | |||||
<code><load-properties></code> task. This is also the reason property | |||||
is one of those tasks which is allowed to exist outside of a target. | |||||
</p> | |||||
<p> As Ant1 evolved new types such as <code><path></code> and | |||||
<code><fileset></code> were added. The concept of datatypes has continued | |||||
to evolve to the point where users can now define new datatypes. It would be | |||||
expected that in addition to new types there will be many sub-types created, | |||||
such as new types of fileset. Ant1, however, does not strongly support such type | |||||
extensibility. When a subtype is created by extending an existing type, Ant1 | |||||
requires it to be either used by reference or all tasks which accept the base | |||||
type need to be modified to support the new type. Use by reference is not always | |||||
possible. It will depend on whether the base type has been coded to support | |||||
references. </p> | |||||
<box> | |||||
<p> | |||||
Support polymorphic behaviour, allowing a build file to pass a subtype to a | |||||
task which is defined to accept the base type. Allow task interfaces to be | |||||
defined in terms of interfaces. | |||||
</p> | |||||
<p> | |||||
Move reference processing to the core to make it more regular removing the | |||||
burden of type developers to explicitly support references. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Project object does too much"> | |||||
<p> | |||||
In Ant1 the Project object takes on too many roles including all of the | |||||
following: | |||||
</p> | |||||
<ul> | |||||
<li>Holds the project model built when parsing the build file</li> | |||||
<li>Holds the run-time state of the build through the properties and current | |||||
task definitions</li> | |||||
<li>Provides context for task execution. All tasks have a reference to their | |||||
project instance and use it to access core functions</li> | |||||
<li>Provides the implementation of common task operations</li> | |||||
<li>Build event management</li> | |||||
<li>Message logging</li> | |||||
<li>Global filter definitions</li> | |||||
<li>Java Version</li> | |||||
<li>Property replacement</li> | |||||
<li>Message Levels</li> | |||||
<li>Utility functions such as boolean conversion and path translation</li> | |||||
<li>Integration point for embedding Ant</li> | |||||
</ul> | |||||
<p> As a class, Project is not cohesive. Reuse of the Ant core functionality is | |||||
difficulty as all of these concerns bring in many other support classes. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Separate the various roles of Project into more cohesive classes. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
</section> | |||||
<section name="Other Goals"> | |||||
<p> | |||||
In addition to the issues which arise from Ant1 limitations, there are a number | |||||
of requirements which have emerged in the mailing list discussions about Ant2. | |||||
This isn't a complete list - just the ones I picked up for Mutant. | |||||
</p> | |||||
<subsection name="Limited project reuse"> | |||||
<p> In Ant1 the only way to reuse build file definitions is to use the | |||||
<code><ant></code> task. While useful, it is relatively coarse-grained. It | |||||
can also be tedious if you are trying to extend an existing project definition - | |||||
that is, adding new targets while retaining a user's ability to access the | |||||
existing targets. </p> | |||||
<p> | |||||
In addition to the extension of projects, it should be possible to compose | |||||
projects creating dependencies between the targets of the different projects, | |||||
and to access the data and definitions of one project by a controlling project | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Allow a project to extend and control other projects | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Ant1 Compatibility - Zero Friction"> | |||||
<p> | |||||
While it has always been accepted that there will be come backward compatibility | |||||
breaks in moving from Ant1 to Ant2, these should be minimized. If the changeover | |||||
from Ant1 to Ant2 is difficult, it may never happen. On the other hand, the | |||||
openness of the Ant1 interface means that some tasks will not work as expected - | |||||
the most difficult being the <code><script></code> task. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Achieve a practical level of compatability without degrading the integrity of | |||||
the core's interfaces. A practical level of compatability is intentionally a | |||||
vague measure but it would require the majority of projects in Gump to be built | |||||
without noticeable differences from Ant1 | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="XML Configuration"> | |||||
<p> | |||||
In Ant1 configuration of Ant is achieved either through the execution of OS | |||||
dependent scripts by the launcher scripts or though properties files which have | |||||
the limited capability to set properties. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Provide an XML based configuration system with rich capabilities to configure | |||||
the operation of Ant. | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
<subsection name="Aspects"> | |||||
<p> | |||||
In Ant1 there are many things which are common to a group of tasks but adding | |||||
the capability to each task is repetitive and tedious. An example would be the | |||||
failonerror attribute which controls whether a task will cause the build to stop | |||||
when it fails. This started on just one task but has since been added to many | |||||
other tasks as users want more fine control over when their builds stop. Aspects | |||||
have been discussed as a mechanism for providing a single implementation of a | |||||
concept or control that can then be applied to tasks independently. | |||||
</p> | |||||
<box> | |||||
<p> | |||||
Investigate the use of an Aspect approach to provide common functionality | |||||
across tasks with a single implementation | |||||
</p> | |||||
</box> | |||||
</subsection> | |||||
</section> | |||||
</body> | |||||
</document> | |||||
@@ -0,0 +1,85 @@ | |||||
<document> | |||||
<properties> | |||||
<author email="">Conor MacNeill</author> | |||||
<title>Mutant Introduction</title> | |||||
</properties> | |||||
<body> | |||||
<section name="Introduction"> | |||||
<p> | |||||
These pages describe the design and implementation of Mutant. | |||||
</p> | |||||
<p> | |||||
For some time, there has been the concept of Ant 2.0, a rearchitecting of | |||||
Ant designed to address the shortcomings in the design of Ant 1.x, while | |||||
drawing the experience gained in that development. This rearchitecting | |||||
would most likely be accompanied by at least some break in backward | |||||
compatability. Over time Ant 2.0 has come to be known as Ant2 and the current | |||||
Ant codebase is generally known as Ant1. | |||||
</p> | |||||
<p> | |||||
Mutant is my proposal, a revolution, for Ant2. Actually, I consider it more | |||||
an evolution of the design and implementation used for Ant1, but in Jakarta | |||||
parlance, being a separate codebase, it is termed a revolution. | |||||
</p> | |||||
<p> | |||||
There is no special significance in the name Mutant. I chose it because, as | |||||
a word, it is an extension of the word Ant and it also signifies a change | |||||
from the previous generation | |||||
</p> | |||||
</section> | |||||
<section name="Other Proposals"> | |||||
<p> | |||||
Mutant is not the only proposed revolution for Ant2. Peter Donald has | |||||
developed another known as | |||||
<a href="http://jakarta.apache.org/ant/myrmidon">Myrmidon</a> | |||||
which presents a different view of how Ant2 could be realized. Other | |||||
people hold the view that Ant1 can continue to evolve and that there | |||||
is no need for rearchitecture of its codebase. I recommend you | |||||
investigate all these points of view. | |||||
</p> | |||||
<p> | |||||
As I write this, no decision has been taken as to which codebase will be | |||||
adopted for Ant2. It may not be Mutant and it could even be some entirely | |||||
new proposal. These pages do not compare and contrast Mutant with these | |||||
other proposals or points of view, at least not explicitly. They are just | |||||
intended to describe how Mutant is designed and implemented and why it is the | |||||
way it is. | |||||
</p> | |||||
</section> | |||||
<section name="Getting Started"> | |||||
<box> | |||||
<h1><font color="red">Caution</font></h1> | |||||
<p> | |||||
Mutant is not even an alpha release. While it is relatively stable, it is | |||||
subject to change. There are no backward compatability guarantees for any of | |||||
the classes, interfaces, build files, configuration, launch scripts, etc that | |||||
Mutant provides. | |||||
</p> | |||||
<p>In particular, some features in Mutant are experimental and may not, in the | |||||
long run, prove to be worthwhile.</p> | |||||
</box> | |||||
<p> | |||||
<a href="goals.html">Start</a> now by looking at the key requirements which have | |||||
shaped the design of Mutant. | |||||
</p> | |||||
<div align="right"> | |||||
<p>Conor MacNeill</p> | |||||
</div> | |||||
</section> | |||||
</body> | |||||
</document> | |||||
@@ -1,50 +1,23 @@ | |||||
<?xml version="1.0" encoding="ISO-8859-1"?> | <?xml version="1.0" encoding="ISO-8859-1"?> | ||||
<project name="Jakarta Site" | |||||
href="http://jakarta.apache.org/"> | |||||
<project name="Mutant Proposal" href="http://jakarta.apache.org/ant/mutant"> | |||||
<title>The Jakarta Site</title> | |||||
<title>Mutant Proposal</title> | |||||
<!-- uncomment and put your project logo here! | <!-- uncomment and put your project logo here! | ||||
<logo href="http://jakarta.apache.org/images/jakarta-logo.gif">The Jakarta Project</logo> | <logo href="http://jakarta.apache.org/images/jakarta-logo.gif">The Jakarta Project</logo> | ||||
--> | --> | ||||
<body> | |||||
<menu name="Apache Ant"> | |||||
<item name="Front Page" | |||||
href="/index.html"/> | |||||
<item name="News" | |||||
href="/antnews.html"/> | |||||
<item name="Documentation" | |||||
href="/manual/index.html"/> | |||||
<item name="External Tools and Tasks" | |||||
href="/external.html"/> | |||||
<item name="Resources" | |||||
href="/resources.html"/> | |||||
<item name="Ant FAQ" | |||||
href="/faq.html"/> | |||||
<item name="Having Problems?" | |||||
href="/problems.html"/> | |||||
</menu> | |||||
<menu name="Download"> | |||||
<item name="Binaries" href="/site/binindex.html"/> | |||||
<item name="Source Code" href="/site/sourceindex.html"/> | |||||
</menu> | |||||
<menu name="Jakarta"> | |||||
<item name="News & Status" href="/site/news.html"/> | |||||
<item name="Mission" href="/site/mission.html"/> | |||||
<item name="Guidelines Notes" href="/site/guidelines.html"/> | |||||
<item name="FAQs" href="/site/faqs.html"/> | |||||
</menu> | |||||
<menu name="Get Involved"> | |||||
<item name="Overview" href="/site/getinvolved.html"/> | |||||
<item name="CVS Repositories" href="/site/cvsindex.html"/> | |||||
<item name="Mailing Lists" href="/site/mail.html"/> | |||||
<item name="Reference Library" href="/site/library.html"/> | |||||
<item name="Bug Database" href="http://nagoya.apache.org/bugzilla/enter_bug.cgi?product=Ant"/> | |||||
<item name="Enhancement Requests" href="http://nagoya.apache.org/bugzilla/enter_bug.cgi?product=Ant&bug_severity=Enhancement"/> | |||||
</menu> | |||||
<body> | |||||
<menu name="Mutant Proposal"> | |||||
<item name="Introduction" | |||||
href="/index.html"/> | |||||
<item name="Design Goals" | |||||
href="/goals.html"/> | |||||
<item name="User Features" | |||||
href="/features.html"/> | |||||
<item name="Task Developers" | |||||
href="/developers.html"/> | |||||
<item name="Design Description" | |||||
href="/design.html"/> | |||||
</menu> | |||||
</body> | </body> | ||||
</project> | </project> |
@@ -12,7 +12,7 @@ | |||||
#set ($subbannerfg = "#ffffff") | #set ($subbannerfg = "#ffffff") | ||||
#set ($tablethbg = "#039acc") | #set ($tablethbg = "#039acc") | ||||
#set ($tabletdbg = "#a0ddf0") | #set ($tabletdbg = "#a0ddf0") | ||||
<!-- start the processing --> | <!-- start the processing --> | ||||
#document() | #document() | ||||
<!-- end the processing --> | <!-- end the processing --> | ||||
@@ -35,6 +35,8 @@ | |||||
#source ($items) | #source ($items) | ||||
#elseif ($items.getName().equals("table")) | #elseif ($items.getName().equals("table")) | ||||
#table ($items) | #table ($items) | ||||
#elseif ($items.getName().equals("box")) | |||||
#box ($items) | |||||
#else | #else | ||||
$xmlout.outputString($items) | $xmlout.outputString($items) | ||||
#end | #end | ||||
@@ -62,6 +64,8 @@ | |||||
#table ($items) | #table ($items) | ||||
#elseif ($items.getName().equals("subsection")) | #elseif ($items.getName().equals("subsection")) | ||||
#subsection ($items) | #subsection ($items) | ||||
#elseif ($items.getName().equals("box")) | |||||
#box ($items) | |||||
#else | #else | ||||
$xmlout.outputString($items) | $xmlout.outputString($items) | ||||
#end | #end | ||||
@@ -29,7 +29,7 @@ | |||||
#if ($value.getAttributeValue("rowspan")) | #if ($value.getAttributeValue("rowspan")) | ||||
#set ($rowspan = $value.getAttributeValue("rowspan")) | #set ($rowspan = $value.getAttributeValue("rowspan")) | ||||
#end | #end | ||||
<td bgcolor="$tabletdbg" colspan="$!colspan" rowspan="$!rowspan" | |||||
<td bgcolor="$tabletdbg" colspan="$!colspan" rowspan="$!rowspan" | |||||
valign="top" align="left"> | valign="top" align="left"> | ||||
<font color="#000000" size="-1" face="arial,helvetica,sanserif"> | <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | ||||
#if ($value.getText().length() != 0 || $value.hasChildren()) | #if ($value.getText().length() != 0 || $value.hasChildren()) | ||||
@@ -48,7 +48,7 @@ | |||||
#if ($value.getAttributeValue("rowspan")) | #if ($value.getAttributeValue("rowspan")) | ||||
#set ($rowspan = $value.getAttributeValue("rowspan")) | #set ($rowspan = $value.getAttributeValue("rowspan")) | ||||
#end | #end | ||||
<td bgcolor="$tablethbg" colspan="$!colspan" rowspan="$!rowspan" | |||||
<td bgcolor="$tablethbg" colspan="$!colspan" rowspan="$!rowspan" | |||||
valign="top" align="left"> | valign="top" align="left"> | ||||
<font color="#000000" size="-1" face="arial,helvetica,sanserif"> | <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | ||||
#if ($value.getText().length() != 0 || $value.hasChildren()) | #if ($value.getText().length() != 0 || $value.hasChildren()) | ||||
@@ -85,7 +85,7 @@ | |||||
#if ($value.getAttributeValue("align")) | #if ($value.getAttributeValue("align")) | ||||
#set ($align=$value.getAttributeValue("align")) | #set ($align=$value.getAttributeValue("align")) | ||||
#end | #end | ||||
<img src="$relativePath$value.getAttributeValue("src")" | |||||
<img src="$relativePath$value.getAttributeValue("src")" | |||||
width="$!width" height="$!height" align="$!align"> | width="$!width" height="$!height" align="$!align"> | ||||
#end | #end | ||||
@@ -111,6 +111,34 @@ | |||||
</div> | </div> | ||||
#end | #end | ||||
#macro ( box $value) | |||||
<div align="left"> | |||||
<table cellspacing="4" cellpadding="0" border="0"> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#ffffff"> | |||||
#if ($value.getText().length() != 0 || $value.hasChildren()) | |||||
$xmlout.outputString($value, true) | |||||
#else | |||||
| |||||
#end | |||||
</td> | |||||
<td bgcolor="#023264" width="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
<tr> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
<td bgcolor="#023264" width="1" height="1"><img src="/images/void.gif" width="1" height="1" vspace="0" hspace="0" border="0"/></td> | |||||
</tr> | |||||
</table> | |||||
</div> | |||||
#end | |||||
#macro ( makeProject ) | #macro ( makeProject ) | ||||
#set ($menus = $project.getChild("body").getChildren("menu")) | #set ($menus = $project.getChild("body").getChildren("menu")) | ||||
#foreach ( $menu in $menus ) | #foreach ( $menu in $menus ) | ||||
@@ -148,16 +176,16 @@ | |||||
<html> | <html> | ||||
<head> | <head> | ||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> | ||||
#set ($authors = $root.getChild("properties").getChildren("author")) | #set ($authors = $root.getChild("properties").getChildren("author")) | ||||
#foreach ( $au in $authors ) | #foreach ( $au in $authors ) | ||||
#metaauthor ( $au.getText() $au.getAttributeValue("email") ) | #metaauthor ( $au.getText() $au.getAttributeValue("email") ) | ||||
#end | #end | ||||
<title>$project.getChild("title").getText() - $root.getChild("properties").getChild("title").getText()</title> | <title>$project.getChild("title").getText() - $root.getChild("properties").getChild("title").getText()</title> | ||||
</head> | </head> | ||||
<body bgcolor="$bodybg" text="$bodyfg" link="$bodylink"> | |||||
<body bgcolor="$bodybg" text="$bodyfg" link="$bodylink"> | |||||
<table border="0" width="100%" cellspacing="0"> | <table border="0" width="100%" cellspacing="0"> | ||||
<!-- TOP IMAGE --> | <!-- TOP IMAGE --> | ||||
<tr> | <tr> | ||||
@@ -168,7 +196,7 @@ | |||||
<tr><td colspan="2"> | <tr><td colspan="2"> | ||||
<hr noshade="" size="1"/> | <hr noshade="" size="1"/> | ||||
</td></tr> | </td></tr> | ||||
<tr> | <tr> | ||||
<!-- LEFT SIDE NAVIGATION --> | <!-- LEFT SIDE NAVIGATION --> | ||||
<td valign="top" nowrap="true"> | <td valign="top" nowrap="true"> | ||||
@@ -187,7 +215,7 @@ | |||||
</td></tr> | </td></tr> | ||||
<tr><td colspan="2"> | <tr><td colspan="2"> | ||||
<div align="center"><font color="$bodylink" size="-1"><em> | <div align="center"><font color="$bodylink" size="-1"><em> | ||||
Copyright © 2000-2002, Apache Software Foundation | |||||
Copyright © 2002, Apache Software Foundation | |||||
</em></font></div> | </em></font></div> | ||||
</td></tr> | </td></tr> | ||||
</table> | </table> | ||||