我使用 Apache Ant 作为工具来完成我必须一遍又一遍地完成的繁琐数据收集和计算任务。我已经定义了一些自定义 Ant 任务,它们工作得非常好。
但是,现在我想使用<typedef>
标签创建新的数据类型。我想在我的开头定义一些数据,build.xml
以后可以参考,就像我的一个 Java 项目的常规构建文件中的以下示例:
<path id="classpath.build">
<fileset dir="${dir.lib}">
<include name="**/*.jar" />
<exclude name="**/junit*" />
</fileset>
</path>
所以我创建了一个简单的 HelloWorld 示例,如下所示:
<sampledata data="LOL" id="someid" />
在自定义 ant 任务中,我想引用此数据类型:
<customtask dataref="someid" />
这似乎很简单,所以在挖掘 API 文档后,我发现我的类必须扩展org.apache.tools.ant.types.DataType
并且必须有方法setRefid(org.apache.tools.ant.types.Reference r)
。
我的自定义 Ant 任务 customtask 对 dataref 属性使用以下代码:
public class CustomTask extends Task {
private SampleData data;
public void setDataref(Reference r) {
data = new SampleData(getProject());
data.setRefid(r);
}
public void execute() {
System.out.println(data.getData());
}
}
我的 SampleData 实现如下:
public class SampleData extends DataType {
private String data;
public SampleData(Project project) {
setProject(project);
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return this.data;
}
public void setRefid(Reference r) {
super.setRefid(r);
}
}
请注意,这一切都基于org.apache.tools.ant.types.Path
显示我想要的行为的来源。
但是,在使用上述自定义任务创建目标后,输出为null
. 因此 SampleData 已实例化,但引用设置不正确。当我调试时,我发现 SampleData 在我的 ant 文件中正确实例化了数据LOL
,甚至参考设置为someid
. 此外,CustomTask
类setDataref
方法确实传递了一个名为的引用someid
,因此setDataref
方法中的一切都出错了,但我不知道我必须做什么,并且缺少手册(或者我错过了一个重要部分)。
我觉得我没有完全掌握带有 id 的自定义数据类型的生命周期。
编辑 23-11-2012 9:24:
经过更多的摆弄和查看源代码后,org.apache.tools.ant.types.Path
我遵循了那里的一些方法,并将我的 SampleData.getData 更改为以下内容:
public String getData() {
if(isReference()) {
return ((SampleData)getCheckedRef()).getData();
}
return this.data;
}
我更进一步,但是现在我在我的中收到以下 Ant 错误build.xml
:
/home/arjan/dev/so-demo/build.xml:9: someid doesn't denote a SampleData
但是,当我检查引用对象封装的类时,它是正确的类型。我现在对此感到非常厌倦。还有什么提示吗?
编辑 23-11-2012 11:46:
我创建了一个带有清晰测试用例的 Gist。我的 Ant 版本是 1.8.4。希望有人会提出解决方案,因为我查看了其他库,如 Sonatype Aether Antlib 并遵循他们的推理方式。
方法都出错了getCheckedRef
,特别是在 Ant 源文件中src\main\org\apache\tools\ant\types\DataType.java:250
:
if (!(requiredClass.isAssignableFrom(o.getClass()))) {
log("Class " + o.getClass() + " is not a subclass of " + requiredClass,
Project.MSG_VERBOSE);
String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
throw new BuildException(msg);
}
到底是怎么回事?这是我能想出的简单测试用例。