开发者

ANT: loadresource task called twice

开发者 https://www.devze.com 2023-04-01 08:50 出处:网络
I have a very basic ant task which is behaving weirdly. It is not more than this build.xml without any dependencies:

I have a very basic ant task which is behaving weirdly.

It is not more than this build.xml without any dependencies:

<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>

The weird thing is, that this is executed twice while everything else in the ant script is only run once.

That means, that http-call arrives twice on the server. i even captured the http traffic using wireshark and it confirms that the http-call is done开发者_如何学C twice.

They even seem to be called exactly at the same time down to the millisecond.

The echo is shown only once in the consoleoutput.

The ant script is launched via eclipse built-in ant, though the problem also persists when called from the windows command line with the standalone ant. So I don't think it is an IDE or target-chain problem.

Thanks for any help on this!

EDIT: for what it's worth, here is a link to the ant task, which i have reported. https://issues.apache.org/bugzilla/show_bug.cgi?id=51762


What you're seeing is undocumented and arguably buggy behavior from Ant. I haven't looked in the bug database, but here's the link if you're interested: http://ant.apache.org/bugs.html

What's happening is the LoadResource task first checks the size of the resource, then reads the stream into a buffer (look for the execute method at line 126). The URLResource class opens the connection to read the Content-Length header, but then closes the connection. This means it has to reopen the connection to get the stream from it.

I believe the close() call at line 282 can and should be removed. However, there may be a reason that the Ant developers put it there. I'll leave it up to you to report/vote for that behavior.


---- Edited to align with full ant file listing, now available ----

Your target dependencies likely cause the task to be called twice. If you want to ensure that it is called only once, put something like this around it:

<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>

If it gets called twice after putting such a guard around it, it's the code within the loadresource implementation of the ant task, or ant is getting called twice by some external item (like an IDE). Either way it is not an error in the dependency chain.

The only way to fix this is to access the url, and check to see if the file needs downloaded; then, if it does need downloaded, download it.

<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>

Under such a framework, the verification will execute every time, but the file will only be updated if the modified times differ. Once the file isn't getting updated every time, other tasks will likely not detect it as new and perform less work (provided they were written to skip already done work, like javac, copy, mkdir, etc).


My workaround was to use :

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

or on Windows: (tested on Windows 7)

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

The dest attribute is required. I didn't actually want to download anything so I am discarding it.

I don't know if this requires any dependencies or not, I had already installed all the ant dependencies before I figured this out.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号