2011-06-15 13 views
9

我有以下的ant腳本,當我的antcontrib的foreach任務的parallel設置爲true時,我似乎無法找到使失敗的方法。有任何想法嗎?並行執行的antcontrib foreach不會引發錯誤

<project name="asdf" > 
    <taskdef resource="net/sf/antcontrib/antcontrib.properties"> 
     <classpath> 
      <pathelement location="../lib/ant/ant-contrib-1.0b3.jar" /> 
     </classpath> 
    </taskdef> 
    <target name="build"> 
     <foreach target="exex-subant" param="foreach.dir" parallel="true" maxthreads="4" inheritall="true" list="1,2,3"> 
      <param name="target" value="build" /> 
     </foreach> 
    </target> 

    <target name="exex-subant"> 
     <fail>test</fail> 
    </target> 
</project> 

回答

9

這是因爲在並行執行時,<foreach>使用<parallel>任務,但不設置「failonany」屬性,或給予任何方式說,如果任何迭代失敗的任務將失敗。

幸運的是,有一個相對簡單的解決方法,即使用<for>而不是<foreach>。在你的榜樣,這應該是這樣的:

<target name="build"> 
    <for param="foreach.dir" parallel="true" list="1,2,3"> 
     <sequential> 
      <antcall target="exex-subant" inheritall="true"> 
       <param name="target" value="build" /> 
       <param name="foreach.dir" value="@{foreach.dir}" /> 
      </antcall> 
     </sequential> 
    </for> 
</target> 

請注意,您必須在foreach.dir屬性,那麼這將是在exex-subant目標爲${foreach.dir}訪問明確地傳遞。

這將並行執行所有迭代,但如果其中任何一個失敗(它不會執行任何超出for任務的任何內容)腳本將失敗。

注意的是,爲了使用for任務,你需要螞蟻1.6或更高版本,並且需要將您的taskdef更改爲:

<taskdef resource="net/sf/antcontrib/antlib.xml"> 
    <classpath> 
     <pathelement location="../lib/ant/ant-contrib-1.0b3.jar" /> 
    </classpath> 
</taskdef> 

如果由於某種原因,你需要支持舊版本的螞蟻,那麼你將不得不稍微改變exex-subant目標,以便它在失敗時改變了一些東西。例如,你可以將當前的邏輯包裝在try/catch中的exex-subant中,並在catch塊中創建一個文件。然後,在foreach終止後,您可以檢查該文件是否存在,如果存在,就會失敗。這樣,如果foreach的任何執行失敗,則在foreach結束後,ant腳本將失敗。

請注意,您不能僅在失敗時在exex-subant中設置屬性,因爲屬性不會傳播回foreach循環(這就是爲什麼我建議創建文件)。但我強烈建議只使用for任務,並要求ant 1.6或更高版本。

+0

謝謝...工作! – Clintm 2011-06-24 16:25:50