将任务或数据类型定义添加到当前项目,以便可以在当前项目中使用这种新类型或任务。
任务是任何扩展 org.apache.tools.ant.Task
的类,或者可以使用适配器类将其适配为任务。
数据类型是诸如 路径 或 文件集 之类的东西,可以在项目级别定义,并通过其 id 属性进行引用。自定义数据类型通常需要自定义任务才能充分利用它们。
需要两个属性来进行定义:唯一标识此数据类型的名称,以及实现此类型的类的完整名称(包括其包名)。
您还可以使用 file 或 resource 属性一次定义一组定义。这些属性指向以 Java 属性文件或 xml 格式的格式的文件。
对于属性文件,每行都以以下格式定义单个数据类型
typename=fully.qualified.java.classname
xml 格式在 Antlib 部分中描述。
如果您正在定义与多个 taskdef
或 typedef
任务共享相同类路径的任务或类型,则相应的类将由不同的 Java 类加载器 加载。通过不同的类加载器加载的两个同名类不是 JVM 意义上的同一个类,它们不共享静态变量,这些类的实例无法访问由“另一个同名类”定义的实例的私有方法或属性。它们甚至不属于同一个 Java 包,也不能访问包私有代码。
加载多个应该通过共享 Java 代码相互协作的任务/类型的最佳方法是使用 resource 属性和 antlib
描述符。如果这不可行,第二好的选择是使用 loaderref 属性并为每个 typedef
/taskdef
指定相同的名称——这样类将共享相同的 ClassLoader
。请注意,typedef
/taskdef
任务必须使用相同的类路径定义(包括路径组件的顺序)才能使 loaderref 属性正常工作。
属性 | 描述 | 必需 |
---|---|---|
name | 数据类型的名称 | 是,除非指定了 file 或 resource 属性。 |
classname | 实现数据类型的完整类名 | |
file | 要从中加载定义的文件的名称。 | 否 |
resource | 要从中加载定义的资源的名称。如果在类路径中找到多个此名称的资源,并且 format 为 properties,则将加载第一个资源;否则将加载所有此类资源。 |
否 |
format | 文件或资源的格式。值是 properties" 或 xml。如果值为 properties,则文件/资源是包含 name-classname 对的属性文件。如果值为 xml,则文件/资源是根据 Antlib 结构化的 XML 文件/资源。默认值为 properties,除非文件/资源名称以 .xml 结尾,在这种情况下,format 属性的值将为 xml。自 Ant 1.6 起 |
否 |
classpath | 查找 classname 时要使用的类路径。 | 否 |
classpathref | 对查找 classname 时要使用的类路径的引用。 | 否 |
loaderRef | 用于加载类的加载器的名称,该加载器由指定的类路径构建。使用此方法允许使用相同的加载器加载多个任务/类型,以便它们可以相互调用。自 Ant 1.5 起 | 否 |
onerror | 如果定义类型时发生错误,要采取的操作。值是 fail:导致构建异常; report:输出警告,但继续; ignore:不执行任何操作。自 Ant 1.6 起,还有一个附加值 failall:导致所有行为失败,以及如果未找到资源或文件,则针对资源或文件属性的构建异常。 |
否;默认值为 fail(自 Ant 1.7 起) |
adapter | 用于将定义的类适配到另一个接口/类的类。适配器类必须实现接口 org.apache.tools.ant.TypeAdapter 。除非定义的类实现/扩展了属性 adaptto定义的类,否则适配器类将用于包装定义的类。如果未设置 adaptto,则将始终包装定义的类。自 Ant 1.6 起 |
否 |
adaptto | 此属性与 adapter 属性一起使用。如果定义的类未实现/扩展此属性指定的接口/类,则适配器类将用于包装该类。自 Ant 1.6 起 | 否 |
uri | 此定义应该所在的 uri。自 Ant 1.6 起 | 否 |
Typedef
的 classpath 属性是 路径状结构,也可以通过嵌套的 classpath
元素设置。
以下片段定义了一个名为 urlset
的类型。
<typedef name="urlset" classname="com.mydomain.URLSet"/>
数据类型现在可供 Ant 使用。类 com.mydomain.URLSet
实现此类型。
假设一个类 org.acme.ant.RunnableAdapter
扩展了 Task
并实现了 org.apache.tools.ant.TypeAdapter
,并且在 execute()
方法中调用了代理对象上的 run()
,则可以使用 Runnable
类作为 Ant 任务。以下片段定义了一个名为 runclock
的任务。
<typedef name="runclock" classname="com.acme.ant.RunClock" adapter="org.acme.ant.RunnableAdapter"/>
以下片段显示了使用 classpathref 和 loaderref 加载两个定义。
<path id="lib.path"> <fileset dir="lib" includes="lib/*.jar"/> </path> <typedef name="filter1" classname="org.acme.filters.Filter1" classpathref="lib.path" loaderref="lib.path.loader"/> <typedef name="filter2" classname="org.acme.filters.Filter2" loaderref="lib.path.loader"/>
如果您想将 antlib 加载到一个特殊的 XML 命名空间中,则 uri 属性很重要
<project xmlns:antcontrib="antlib:net.sf.antcontrib"> <taskdef uri="antlib:net.sf.antcontrib" resource="net/sf/antcontrib/antlib.xml" classpath="path/to/ant-contrib.jar"/>
这里,命名空间声明 xmlns:antcontrib="antlib:net.sf.antcontrib"
允许使用 antcontrib 前缀(如 <antcontrib:if>
)使用 Ant-Contrib Antlib 的任务和类型。XML 命名空间的正常规则适用,您可以在任何元素上声明前缀,使其可用于声明它的元素及其所有子元素。