Java 带有引用的自定义Ant类型导致空类
我正在使用ApacheAnt作为一种工具来完成繁琐的数据收集和计算任务,我必须一遍又一遍地完成这些任务。我已经定义了一些定制的Ant任务,它们工作得非常好 但是,现在我想使用Java 带有引用的自定义Ant类型导致空类,java,ant,customization,Java,Ant,Customization,我正在使用ApacheAnt作为一种工具来完成繁琐的数据收集和计算任务,我必须一遍又一遍地完成这些任务。我已经定义了一些定制的Ant任务,它们工作得非常好 但是,现在我想使用标记创建新的数据类型。我想在build.xml的开头定义一些数据,稍后我可以参考这些数据,非常类似于我的一个Java项目的常规构建文件中的以下示例: <path id="classpath.build"> <fileset dir="${dir.lib}"> <inclu
标记创建新的数据类型。我想在build.xml
的开头定义一些数据,稍后我可以参考这些数据,非常类似于我的一个Java项目的常规构建文件中的以下示例:
<path id="classpath.build">
<fileset dir="${dir.lib}">
<include name="**/*.jar" />
<exclude name="**/junit*" />
</fileset>
</path>
我的SampleData实现如下所示:
<sampledata data="LOL" id="someid" />
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);
}
}
<jar basedir="cls" destfile="${ant.home}/lib/demo.jar" />
<delete dir="cls" />
请注意,这些都是基于org.apache.tools.ant.types.Path
中的源代码,它显示了我想要的行为
但是,使用上面定义的customtask创建目标后,输出为null
。因此SampleData被实例化,但引用设置不正确。当我调试时,我发现SampleData在我的ant文件中被正确地实例化为dataLOL
,甚至refence也被设置为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;
}
我更进一步了一点,但是现在我在build.xml
中发现了以下Ant错误:
/home/arjan/dev/so-demo/build.xml:9: someid doesn't denote a SampleData
但是,当我检查由引用对象封装的类时,它是正确的类型。
我现在已经受够了。还有什么建议吗
编辑23-11-2012 11:46:
我用一个清晰的测试用例创建了一个要点。我的Ant版本是1.8.4。
希望有人能提供一个解决方案,因为我已经查看了其他库,如Sonatype Ether Antlib,并遵循了他们的推理方式
在getCheckedRef
方法中,尤其是在Ant sourcefilesrc\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);
}
发生了什么事?这是我能想到的最简单的测试用例。我认为问题在于您没有为类中的数据提供setter。。。这对于CustomTask是必需的
public class CustomTask extends Task {
private SampleData data;
public void setDataref(Reference r) {
data = new SampleData(getProject());
data.setRefid(r);
}
public void setData(SampleData data){
this.data = data;
}
public void execute() {
System.out.println(data.getData());
}
}
希望这有帮助。我用上面的要点解决了它!这个问题有两个方面,但我不知道如何解决第二个问题
问题1
不知何故,typedef
和taskdef
标记的classpathref
参数不是好办法。我将它们定向到cls
目录中我编译的类
因此,我决定将所有文件放入jar,并将它们放入{ant.home}/lib
目录中,如下所示:
<sampledata data="LOL" id="someid" />
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);
}
}
<jar basedir="cls" destfile="${ant.home}/lib/demo.jar" />
<delete dir="cls" />
事实证明,从命令行运行没有问题
底线
这个问题可以通过减少我的类型和任务并从命令行运行来解决。将classpathref
与typedef
或taskdef
一起使用会导致someid不表示SampleData
错误。使用Eclipse导致类未找到
错误
我必须说的是奇怪的行为,我想知道如何使Eclipse正确地处理自定义任务,因为这必须是可能的
嗯。。。这花费了我几个小时。我相信这可能会解决您的问题,我遇到了类似的错误:
您缺少自定义任务和类型的loaderRef指令。请参阅:如果定义的任务或类型与多个taskdef或typedef任务共享同一类路径,则相应的类将由不同的Java类加载器加载。从Java VM的角度来看,通过不同类加载器加载的两个同名类不是同一个类,它们不共享静态变量,这些类的实例不能访问由同名“另一个类”定义的实例的私有方法或属性。它们甚至不属于同一个Java包,也不能访问包私有代码
因此,当您通过typedef和taskdef定义自定义任务和自定义类型时,请使用loaderRef属性-这可以是任何属性(如customTaskLoader),只要任务和类型定义之间相同即可
在此基础上,您可以进一步简化代码:
public class CustomTask extends Task {
private SampleData data;
public void execute() {
System.out.println(data.getData());
}
}
及
}我尝试了您的建议,但通过调试,我发现从未调用过该方法。。。。太糟糕了。
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() {
if(isReference()) {
return ((SampleData)getCheckedRef()).getData();
}
return this.data;
}