2011-06-15 50 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