ANT:两次调用loadresource任务

时间:2011-09-02 14:06:07

标签: java ant

我有一个非常基本的蚂蚁任务,表现得非常奇怪。

只有没有任何依赖关系的build.xml:

<project name="Test" default="recreate-via-http" >

    <target name="recreate-via-http">
        <loadresource property="result" >
            <url url="http://someserver/somecall.php"  />           
        </loadresource>  
        <echo>${result}</echo>
    </target>

</project>

奇怪的是,这是执行两次,而ant脚本中的其他所有内容只运行一次。

这意味着,http-call在服务器上到达两次。我甚至使用wireshark捕获了http流量,并确认http呼叫已完成两次。

它们甚至似乎同时被称为毫秒级。

回调仅在consoleoutput中显示一次。

ant脚本是通过eclipse内置的ant启动的,但是当使用独立的ant从windows命令行调用时问题也会持续存在。所以我不认为它是IDE或目标链问题。

感谢您提供任何帮助!

编辑:对于它的价值,这里是我已经报告的蚂蚁任务的链接。 https://issues.apache.org/bugzilla/show_bug.cgi?id=51762

3 个答案:

答案 0 :(得分:1)

你所看到的是无证件,可以说是Ant的错误行为。我没有看过bug数据库,但是如果你感兴趣的话,这里是链接:http://ant.apache.org/bugs.html

正在发生的事情是LoadResource任务首先检查资源的大小,然后将流读入缓冲区(在第126行查找执行方法)。 URLResource类打开连接以读取Content-Length标头,但随后关闭连接。这意味着它必须重新打开连接才能从中获取流。

我相信可以而且应该删除第282行的close()电话。但是,Ant开发人员可能有理由将其放在那里。我会留给你报告/投票支持这种行为。

答案 1 :(得分:0)

----编辑与完整的ant文件列表对齐,现在可用----

您的目标依赖项可能会导致任务被调用两次。如果你想确保它只被调用一次,就把这样的东西放在它周围:

<target name="recreate-via-http" unless="recreate-via-http.done">
  <property name="recreate-via-http.done" value="true"/>
  <loadresource property="result" >
    <url url="http://someserver/somecall.php"  />           
  </loadresource> 
  <echo>${result}</echo>
</target>

如果在将这样的防护措施围绕它之后被调用两次,那么它就是ant任务的loadresource实现中的代码,或者某个外部项目(如IDE)会调用ant两次。无论哪种方式,它都不是依赖链中的错误。

解决此问题的唯一方法是访问网址,并检查文件是否需要下载;然后,如果它确实需要下载,请下载它。

<target name="recreate-via-http">
   <antcall="check.recreate-via-http"/>
   <antcall="execute.recreate-via-http"/>
</target>

<target name="check.recreate-via-http">
   ... access the remote URL, and
       get it's last modified time
   ... access the local file copy, and
       get it's last modified time
   ... call an ant condition to determine
       if the two times are the same, setting
       a property 'execute.recreate-via-http.notNeeded'
       if they are identical.
</target>

<target name="execute.recreate-via-http" unless="execute.recreate-via-http.notNeeded">
   <loadresource property="result" >
     <url url="http://someserver/somecall.php"  />           
   </loadresource> 
   <echo>${result}</echo>
</target>

在这样的框架下,验证将每次执行,但只有在修改的时间不同时才会更新文件。一旦文件没有每次更新,其他任务可能不会将其检测为新的并执行较少的工作(前提是它们被编写为跳过已完成的工作,如javac,copy,mkdir等)。

答案 2 :(得分:0)

我的解决方法是使用:

<get src="http://yourURL" dest="/dev/null" />

或在Windows上:(在Windows 7上测试)

<get src="http://yourURL" dest="NUL" />

dest属性是必需的。我实际上并不想下载任何东西,所以我要丢弃它。

我不知道这是否需要任何依赖关系,在我弄清楚之前,我已经安装了所有的ant依赖项。