You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

features.xml 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. <document>
  2. <properties>
  3. <author email="">Conor MacNeill</author>
  4. <title>Mutant Features</title>
  5. </properties>
  6. <body>
  7. <section name="User Features">
  8. <p>
  9. This page describes the major features in Mutant which are significantly
  10. different from those of Ant1. These are covered from a user perspective. Other
  11. pages describe the differences from the perspectives of a task developer and an
  12. Ant core developer.
  13. </p>
  14. </section>
  15. <section name="Directory Layout">
  16. <p>
  17. When Mutant is installed, the most immediately obvious difference will be in the
  18. directory layout, particularly the lib directory. Where Ant1's lib directory
  19. contained ant.jar, optional.jar and the bundled XML jars, Mutant's lib directory
  20. contain a number of subdirectories.
  21. </p>
  22. <p>
  23. In the root directory, there are a number of jars. These jars are the startup
  24. jars
  25. </p>
  26. <table>
  27. <tr>
  28. <td>init.jar</td>
  29. <td>a set of low level utility routines required at startup</td>
  30. </tr>
  31. <tr>
  32. <td>start.jar</td>
  33. <td>the Mutant launcher class</td>
  34. </tr>
  35. <tr>
  36. <td>ant.jar</td>
  37. <td>old Ant1 entry point</td>
  38. </tr>
  39. </table>
  40. <p>
  41. The subdirectories have the following functions
  42. </p>
  43. <table>
  44. <tr>
  45. <td>parser</td>
  46. <td>The XML parser jars. This is not available to task libraries unless
  47. they explicitly indicate that it is required.</td>
  48. </tr>
  49. <tr>
  50. <td>antcore</td>
  51. <td>Mutant's core classes. These classes are not available to
  52. tasks.</td>
  53. </tr>
  54. <tr>
  55. <td>common</td>
  56. <td>classes which are available to both the core and all task
  57. libraries.</td>
  58. </tr>
  59. <tr>
  60. <td>syslibs/antlibs</td>
  61. <td>Task libraries. The distinction between the two is
  62. discussed below.</td>
  63. </tr>
  64. <tr>
  65. <td>frontend</td>
  66. <td>Ant Frontends. Different frontends may be plugged in by placing
  67. jars here.</td>
  68. </tr>
  69. </table>
  70. <p>
  71. The directory a jar is in will control the visibility of the jar's classes and
  72. resources. This is closely related to the classloader hiearchy used by
  73. Mutant.
  74. </p>
  75. </section>
  76. <section name="Ant Libraries">
  77. <p>
  78. Mutant supports the concept of Ant Libraries. These are collections of
  79. components (tasks and types) and their supporting classes packaged into a
  80. Jar. In Mutant each library has a globally unique identifier. This identifier
  81. uses the same conventions as Java package naming - i.e. a reverse DNS name.
  82. </p>
  83. <p> The jar does not need to be exclusively for Ant. For example, it may be the
  84. jar for a tool which wishes to provide some Ant tasks for using the tool. It
  85. could be the main jar of an appication server that bundles Ant tasks for
  86. deployment. The jar does not even need to be installed in Mutant's antlib
  87. directory - Mutant can be configured to look in jars in other locations for Ant
  88. Libraries. </p>
  89. <subsection name="Ant library descriptor">
  90. <p>
  91. Whatever the jar contains and wherever it is located, Mutant looks for an XML
  92. based descriptor in the jar at META-INF/antlib.xml. This XML file describes the
  93. components in the jar that will be available to Mutant.
  94. </p>
  95. <p>
  96. Here is an example of the descriptor.
  97. </p>
  98. <source><![CDATA[
  99. <antlib libid="ant.system"
  100. home="http://jakarta.apache.org/ant">
  101. <taskdef name="libpath" classname="org.apache.ant.antlib.system.LibPath"/>
  102. <taskdef name="loadlib" classname="org.apache.ant.antlib.system.LoadLib"/>
  103. <taskdef name="import" classname="org.apache.ant.antlib.system.Import"/>
  104. <converter classname="org.apache.ant.antlib.system.FileConverter"/>
  105. <converter classname="org.apache.ant.antlib.system.URLConverter"/>
  106. <converter classname="org.apache.ant.antlib.system.PrimitiveConverter"/>
  107. <aspect classname="org.apache.ant.antlib.system.AntAspect"/>
  108. </antlib>
  109. ]]></source>
  110. <p>
  111. As a user you generally won't need to worry about this decriptor. The library
  112. developer will have developed it to describe their library. Mutant uses the
  113. descriptor to understand what Ant related components the library provides.
  114. </p>
  115. </subsection>
  116. <subsection name="Loading libraries">
  117. <p>
  118. Library management in Mutant is split into two phases - a loading phase and an
  119. import phase. The loading phase is where Mutant loads the antlib.xml descriptor
  120. from the library. After loading, Mutant knows where the library is located and
  121. what components it provides. In general Mutant will not make the components
  122. available to build scripts automatically. A build script needs to notify Mutant
  123. what components it is using from each library. This is known as importing.
  124. </p>
  125. <p> Mutant loads libraries from two locations within the Mutant directory
  126. structure when Mutant starts up - the lib/syslibs and lib/antlibs directories.
  127. The distinction between these two locations is explained in the configuration
  128. discussion below. All jars in these directories will be search for library
  129. descriptors. All libraries providing descriptors will be available for importing
  130. into builds</p>
  131. <p> In addition to the automatically loaded libraries, it is possible to
  132. explicitly request additional libraries to be loaded using the
  133. <code>&lt;loadlib&gt;</code> task. Individual libraries may be loaded or a set
  134. of libraries loaded from a directory. Libraries may also be loaded from remote
  135. locations by specifying a URL. The loadlib task can request that all components
  136. in the loaded library also be imported at the time of loading. Examples of the
  137. loadlib task follow </p>
  138. <source><![CDATA[
  139. <!-- load a library from a specific file and import all components -->
  140. <loadlib file="/opt/tools/toollib.jar" importall="true"/>
  141. <!-- load all libraries from a directory -->
  142. <loadlib dir="/opt/appserver/lib/"/>
  143. <!-- load libraries from a remote server -->
  144. <loadlib url="http://jakarta.apache.org/ant/testtasks.jar"/>
  145. ]]></source>
  146. <p>
  147. In general the loading of libraries from absolute locations would be a
  148. configuration task. These would be specified in the Mutant configuration file
  149. and would not be used in a build file. The loading of project libraries from
  150. relative locations may be something that you would see in a build file.
  151. </p>
  152. </subsection>
  153. <subsection name="Importing components">
  154. <p>
  155. Mutant is designed to allow tasks to be defined simply by dropping a jar in a
  156. directory or configuring Mutant to look in particular places for jars. This will
  157. allow tasks and types developed by many different developers to be used. With
  158. many developers developing tasks, however, inevitably some tasks will end up
  159. with the same name.
  160. </p>
  161. <p>
  162. This is very similar to the situation faced by Java with Java class names.
  163. Many Java classes have the same name. When a Java programmer uses a class they
  164. must import that class with an import statement. This tells the Java compiler
  165. which particular class is being referenced by the classname. Effectively the
  166. import statement creates a mapping from a name used in the Java source file and
  167. a class in the global package namespace.
  168. </p>
  169. <p>
  170. Mutant provides an import task to specify, in a manner similar to Java's import
  171. statement, which components are being used. When a component is imported the
  172. library is identified by its unique id. By default the component is imported
  173. into the frame using the name it is known by within the library. When this would
  174. conflict with a name that has already been imported, the import task allows the
  175. component to be given a new name, or alias, by which it will be referenced. It
  176. is also possible to import all the components in a library. The folowing example
  177. shows the various methods by which the import task can be used to import
  178. components.
  179. </p>
  180. <source><![CDATA[
  181. <!-- import the runtool task from the com.foo.tools library -->
  182. <import libraryId="com.foo.tools" name="runtool"/>
  183. <!-- import the runtool task from the com.bar.tools library and
  184. alias it since the runtool is already defined -->
  185. <import libraryId="com.bar.tools" name="runtool" alias="runbartool"/>
  186. <!-- import all of the tasks from the com.fubar.tools library -->
  187. <import libraryId="com.fubar.tools"/>
  188. ]]></source>
  189. <p>
  190. By using library identifiers, import operations are not tied to a particular
  191. library location. The separation of the loading and importing into separate
  192. phases allows environment-dependent locations to be specified as configuration
  193. information and location independent importing to be specified in the build
  194. file. This is similar to the case of Java imports. Java classes are imported by
  195. their global name without needing to known where the classfile is that contains
  196. that class. That information is provided externally in the CLASSPATH variable.
  197. </p>
  198. </subsection>
  199. <subsection name="Library classpath management">
  200. <p>
  201. Many libraries will have dependencies on external jars. For example, a task
  202. might make use of regular-expression libraries such as jakarta-regexp or a task
  203. may provide a wrapper around some external tool. In these cases the task will
  204. usually need to have the required classes available in the classloader from
  205. which the task itself was loaded. It is possible to avoid these direct
  206. dependencies using techniques such as reflection and explicitly loading the
  207. required classes through additional classloaders but the code is often harder to
  208. write and understand.
  209. </p>
  210. <p> It is not always possible or desirable to bundle the required classes in the
  211. task's jar nor is it desirable that the system classpath contains the required
  212. classes. In fact it is often preferable to run Mutant with an empty classpath.
  213. Buildfiles which do not assume that the system classpath contains particular
  214. classes are generally more portable. Mutant provides a task,
  215. <code>&lt;libpath&gt;</code>, to allow additional paths to be assodicated with a
  216. library. As with the loadlib task, the libpath task may be used to associate a
  217. single file, all jars in a directory or remote jars with a library. </p>
  218. <source><![CDATA[
  219. <libpath libraryid="ant.ant1compat"
  220. dir="/home/conor/jakarta-ant/lib/optional/"/>
  221. ]]></source>
  222. <p> The above example associates all the jars in
  223. /home/conor/jakarta-ant/lib/optional/ with the library whose unique id is
  224. ant.ant1compat. A path must be associated with a library before any components
  225. are imported from the library. Mutant associates the paths with the library and
  226. at the time a component is requested from the library, Mutant will form the
  227. classloader that will be used. The additional paths are added to the definition
  228. of the classloader. Once a component is loaded, further paths will not have any
  229. effect. For this reason, and since the additonal paths are likely to be absolute
  230. paths, the <code>&lt;libpath&gt;</code> task is normally used in Mutant's
  231. configuration phase. </p>
  232. </subsection>
  233. <subsection name="Automatic Imports">
  234. <p>
  235. Mutant will automatically import all components of any library whose unique
  236. identifier begins with &quot;ant.&quot; when the ;library is loaded. This is
  237. mainly a convenience to provide a minimum set of tasks with which to construct
  238. build files.
  239. </p>
  240. </subsection>
  241. </section>
  242. <section name="Includes">
  243. <p>Mutant provides a mechanism for including build file fragments into a build
  244. file. This following example illustrates how this works</p>
  245. <source><![CDATA[
  246. build.ant
  247. ==========
  248. <project default="main" xmlns:ant="http://jakarta.apache.org/ant">
  249. <ant:include fragment="fragment.ant"/>
  250. </project>
  251. fragment.ant
  252. ============
  253. <fragment>
  254. <target name="main">
  255. <echo message="main target"/>
  256. </target>
  257. </fragment>
  258. ]]></source>
  259. <p> The include mechanism can be used to include a complete project file or as
  260. shown in the example, a fragment. When including a project, any attributes on
  261. the included <code>&lt;project&gt;</code> element are ignored and the contents
  262. of the project inserted into the including project. In all cases the included
  263. files must be a well formed XML file containing a root element. </p>
  264. <box>
  265. <p><font color="red">This area of Mutant is subject to change.</font></p>
  266. <p>At present include elements are processed at parse-time. As such they can
  267. only occur at the top-level of the build file. They cannot occur in a target.
  268. The use of the namespace to qualify the include element is intended to convey
  269. the fact that this is not part of the build structure.</p>
  270. <p>An alternative approach would be to define include as a regular task. When an
  271. include is processed, the top-level tasks of the included project would be
  272. executed immediately and the targets added to the current project
  273. structure.</p>.
  274. </box>
  275. </section>
  276. <section name="Project References">
  277. <subsection name="Creating references">
  278. <p>
  279. Mutant allows build file writers to reference properties and targets in other
  280. projects by creating a project reference. Project references are introduced
  281. using the ref task.
  282. </p>
  283. <source><![CDATA[
  284. <!-- create a reference to the main build -->
  285. <ref project="main.xml" name="main"/>
  286. <ref project="test.xml" name="test">
  287. <property name=build.dir" value="build/test"/>
  288. </ref>
  289. ]]></source>
  290. <p>
  291. The above example creates two project references - one to the build in main.xml
  292. and one to the build in test.xml. When a reference is created, it must be given
  293. a label. This label will be used to refer to items within the referenced
  294. project (see below). Note that the ref task is a regular task and the reference
  295. is only created when the ref task is executed. A ref task may be placed at the
  296. top level of a build to effectively create static references. Alternatively a
  297. reference may be created dynamically by putting the ref task in a target.
  298. </p>
  299. </subsection>
  300. <subsection name="Referencing project items">
  301. <p>
  302. The label given to a project reference is used when accessing items within the
  303. project. So, to access the build.dir property in the project referenced by the
  304. main label, you would use main:build.dir. Similarly the compile target would be
  305. referred to as main:compile. Since the referenced projects may also create their
  306. own project references, labels may be concatenated to access items at arbitrary
  307. depths. For example, if main.xml referenced another project under the label
  308. &quot;sub&quot;, a property debug could be referenced as main:sub:debug. The
  309. following example shows various items in the referenced project being used.
  310. </p>
  311. <source><![CDATA[
  312. <!-- Specify the build.dir in the main project prior to the reference
  313. being created -->
  314. <property name="main:build.dir" value="build/main"/>
  315. <!-- create the reference to the main build -->
  316. <ref project="main.xml" name="main"/>
  317. <!-- create the reference to the test build -->
  318. <ref project="test.xml" name="test">
  319. <property name="build.dir" value="build/test"/>
  320. </ref>
  321. <!-- our main target calls the fubar target in the main build -->
  322. <target name="main">
  323. <antcall target="main:fubar"/>
  324. </target>
  325. <!-- Our alt target depends on the fubar target in the main build -->
  326. <target name="alt" depends="main:fubar">
  327. <echo message="main's debug flag is ${main:debug}"/>
  328. </target>
  329. ]]></source>
  330. <p>
  331. When a project is referenced, the top level tasks of the referenced project are
  332. run to allow the project to initialize itself. Mutant allows the referring
  333. build to set a property in a referenced project before the reference is
  334. created. When the reference is eventually created these properties are set
  335. before initialization occurs. In normal Ant fashion, these overriding
  336. properties take precedence. In particular properties in the referenced projects
  337. may be set from the command line as this example shows
  338. </p>
  339. <source>
  340. mutant -Dmain:build.dir=temp
  341. </source>
  342. <p>
  343. The example above shows a target in the referenced project being used as a
  344. dependency and also as a target in an antcall. Since refs are dynamic, Mutant
  345. will only evaluate such dependencies when required. If the alt target were
  346. never to be run, the dependency on main:fubar would never be checked.
  347. </p>
  348. <p>
  349. The import task allows components defined in a referenced project to be brought
  350. into the main build. For example, the following will bring the definition of
  351. tool from the test project in the build. The imported component may also be
  352. aliased to a new name.
  353. </p>
  354. <source><![CDATA[
  355. <!-- import a task definition from another project -->
  356. <import ref="test:tool"/>
  357. ]]></source>
  358. </subsection>
  359. </section>
  360. <section name="Configuration">
  361. <p>
  362. As discussed above Mutant provides a number of tasks to manage libraries and
  363. it is appropriate to run many of these tasks as part of a user or system-wide
  364. configuration rather than incorporating them into the build file. Mutant
  365. provides a configuration system to support running these tasks at an appropriate
  366. time. A Mutant configuration file looks as follows
  367. </p>
  368. <source><![CDATA[
  369. <antconfig allow-unset-properties="true">
  370. <global-tasks>
  371. <libpath libraryid="ant.ant1compat"
  372. file="/home/conor/dev/jakarta-ant/lib/optional/"/>
  373. </global-tasks>
  374. <project-tasks>
  375. <import libraryid="antopt.monitor"/>
  376. </project-tasks>
  377. </antconfig>
  378. ]]></source>
  379. <p>
  380. The antconfig element is the root element of the configuration file. It supports
  381. three attributes
  382. </p>
  383. <table>
  384. <tr>
  385. <td>allow-unset-properties</td>
  386. <td>controls whether Mutant will fail a build which
  387. refers to a property which has not been set. This defaults to the Ant1 behaviour
  388. (true)</td>
  389. </tr>
  390. <tr>
  391. <td>allow-remote-library</td>
  392. <td>controls whether Mutant uses components defined in remote libraries</td>
  393. </tr>
  394. <tr>
  395. <td>allow-remote-project</td>
  396. <td>controls whether Mutant can run a project or reference a project which is
  397. located remotely.</td>
  398. </tr>
  399. </table>
  400. <p>
  401. The configuration provides two collections of configuration tasks, global-tasks
  402. and project-tasks. Global-tasks are run once and are run in the context of the
  403. main project - i.e. the build file identified on the command line (defaults to
  404. build.xml/build.ant), whilst project-tasks are run as part of the initialization
  405. of every project including referenced projects and antcall projects. Looking at
  406. the above example, the global-tasks associate a path with the ant.ant1compat
  407. library while the per-project tasks import the antopt.monitor library into every
  408. project that Mutant processes.
  409. </p>
  410. <p>
  411. The tasks that can be run in the configuration phase are regular tasks but not
  412. all tasks are automatically available. This is the difference between the
  413. syslibs and antlibs directories. The global tasks are run after the syslibs
  414. libraries have been loaded but prior to the antlibs libraries being loaded. The
  415. syslibs library tasks are therefore available in the configuration phase. This
  416. arrangement is to allow the configuration tasks to setup library paths for the
  417. libraries contained in the antlibs directory, especially libraries in the Ant
  418. namespace which are automatically imported at the time they are loaded.
  419. </p>
  420. <p>
  421. If it is required to use tasks from libraries installed in the antlibs
  422. directory, the configuration tasks may explicitly load the library and import
  423. the required tasks. The following example shows the loading and use of the echo
  424. task in the configuration tasks. Note that the ant.home property has been set at
  425. the time the configuration tasks are started.
  426. </p>
  427. <source><![CDATA[
  428. <antconfig allow-unset-properties="true">
  429. <global-tasks>
  430. <loadlib file="${ant.home}/lib/antlibs/ant1compat.jar" importall="true"/>
  431. <echo message="Starting the build"/>
  432. </global-tasks>
  433. <project-tasks>
  434. <echo message="Starting new project"/>
  435. </project-tasks>
  436. </antconfig>
  437. ]]></source>
  438. <p>
  439. When Mutant starts up it will load configurations from two locations - The file
  440. .ant/conf/antconfig.xml in the user's home directory and the file
  441. conf/antconfig.xml in the Mutant home directory. In addition, config files can
  442. be specified on the command line using a -config argument. This allows project
  443. specific configurations to be used.
  444. </p>
  445. </section>
  446. <section name="Targetless builds">
  447. <p>
  448. Mutant allows any task or datatype to be placed outside of a target. All such
  449. components are processed when the project is initialized and before any targets
  450. are processed. In fact Mutant does not require that a project contain any
  451. targets. In this case the only operations performed are the top level tasks at
  452. project initialization. The following shows a simple example
  453. </p>
  454. <source><![CDATA[
  455. <project>
  456. <echo message="Welcome to Mutant"/>
  457. </project>
  458. ]]></source>
  459. </section>
  460. <section name="Extensibility">
  461. <p>
  462. Normally when a task supports a nested element, Ant automatically determines the
  463. type of the nested element and creates an instance of this type. This instance is
  464. then configured and passed to the task. Mutant extends this scheme by allowing
  465. a build file writer to specify the type of nested element to use rather than
  466. relying on the core to determine it. Mutant will process attributes and further
  467. nested elements based on the specified type. For example:
  468. </p>
  469. <source><![CDATA[
  470. <copy todir="dest">
  471. <fileset xsi:type="classfileset" dir="../../bin/ant1compat/">
  472. <root classname="org.apache.tools.ant.Project"/>
  473. </fileset>
  474. </copy>
  475. ]]></source>
  476. <p>
  477. In this example the nested element is actually a classfileset which supports the
  478. &lt;root&gt; nested element. The actual type is specified using the notation from
  479. XML Schema. Mutant predclares the XML Schema namespace under the xsi prefix. You
  480. may explicitly declare this in the build file's XML and use a different prefix
  481. if you wish. For example, this is equivalent to the above
  482. </p>
  483. <source><![CDATA[
  484. <?xml version="1.0"?>
  485. <project xmlns:schema="http://www.w3.org/2001/XMLSchema-instance"
  486. name="test" default="main">
  487. <target name="main">
  488. <delete dir="dest"/>
  489. <mkdir dir="dest"/>
  490. <copy todir="dest">
  491. <fileset schema:type="classfileset" dir="../../bin/ant1compat/">
  492. <root classname="org.apache.tools.ant.Project"/>
  493. </fileset>
  494. </copy>
  495. </target>
  496. </project>
  497. ]]></source>
  498. </section>
  499. <section name="Default build file">
  500. <p>In Ant1, the default build file name is build.xml. In Mutant, the default
  501. build file is build.ant. If build.xnt cannot be found, Mutant will then look for
  502. build.xml. This allows you to support both Ant1 and Ant2 users. The build.xml
  503. file can contain an Ant1 build file. The build.ant file can include or reference
  504. this build and make use of Mutant's capabilities such as library management,
  505. library path settings, etc.
  506. </p>
  507. </section>
  508. </body>
  509. </document>