类型定义

描述

将任务或数据类型定义添加到当前项目,以便可以在当前项目中使用这种新类型或任务。

任务是任何扩展 org.apache.tools.ant.Task 的类,或者可以使用适配器类将其适配为任务。

数据类型是诸如 路径文件集 之类的东西,可以在项目级别定义,并通过其 id 属性进行引用。自定义数据类型通常需要自定义任务才能充分利用它们。

需要两个属性来进行定义:唯一标识此数据类型的名称,以及实现此类型的类的完整名称(包括其包名)。

您还可以使用 file 或 resource 属性一次定义一组定义。这些属性指向以 Java 属性文件或 xml 格式的格式的文件。

对于属性文件,每行都以以下格式定义单个数据类型

typename=fully.qualified.java.classname

xml 格式在 Antlib 部分中描述。

如果您正在定义与多个 taskdeftypedef 任务共享相同类路径的任务或类型,则相应的类将由不同的 Java 类加载器 加载。通过不同的类加载器加载的两个同名类不是 JVM 意义上的同一个类,它们不共享静态变量,这些类的实例无法访问由“另一个同名类”定义的实例的私有方法或属性。它们甚至不属于同一个 Java 包,也不能访问包私有代码。

加载多个应该通过共享 Java 代码相互协作的任务/类型的最佳方法是使用 resource 属性和 antlib 描述符。如果这不可行,第二好的选择是使用 loaderref 属性并为每个 typedef/taskdef 指定相同的名称——这样类将共享相同的 ClassLoader。请注意,typedef/taskdef 任务必须使用相同的类路径定义(包括路径组件的顺序)才能使 loaderref 属性正常工作。

参数

属性 描述 必需
name 数据类型的名称 是,除非指定了 fileresource 属性。
classname 实现数据类型的完整类名
file 要从中加载定义的文件的名称。
resource 要从中加载定义的资源的名称。如果在类路径中找到多个此名称的资源,并且 formatproperties,则将加载第一个资源;否则将加载所有此类资源。
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 起

作为嵌套元素指定的参数

classpath

Typedefclasspath 属性是 路径状结构,也可以通过嵌套的 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"/>

以下片段显示了使用 classpathrefloaderref 加载两个定义。

<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 命名空间的正常规则适用,您可以在任何元素上声明前缀,使其可用于声明它的元素及其所有子元素。