Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带有引用的自定义Ant类型导致空类_Java_Ant_Customization - Fatal编程技术网

Java 带有引用的自定义Ant类型导致空类

Java 带有引用的自定义Ant类型导致空类,java,ant,customization,Java,Ant,Customization,我正在使用ApacheAnt作为一种工具来完成繁琐的数据收集和计算任务,我必须一遍又一遍地完成这些任务。我已经定义了一些定制的Ant任务,它们工作得非常好 但是,现在我想使用标记创建新的数据类型。我想在build.xml的开头定义一些数据,稍后我可以参考这些数据,非常类似于我的一个Java项目的常规构建文件中的以下示例: <path id="classpath.build"> <fileset dir="${dir.lib}"> <inclu

我正在使用ApacheAnt作为一种工具来完成繁琐的数据收集和计算任务,我必须一遍又一遍地完成这些任务。我已经定义了一些定制的Ant任务,它们工作得非常好

但是,现在我想使用
标记创建新的数据类型。我想在
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文件中被正确地实例化为data
LOL
,甚至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 sourcefile
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);
}

发生了什么事?这是我能想到的最简单的测试用例。

我认为问题在于您没有为类中的数据提供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;
 }