Apache Ant:当ant进程终止时,终止由<exec>启动的进程

我有一个使用<exec>执行冗长构build操作的ant任务。 Ant由Windows命令行中的batch file启动。 如果通过closures窗口来终止ant任务,由<exec>启动的进程将继续运行。 当ant进程本身终止时,我怎样才能终止产生的进程呢?

在Windows 7 x64上使用Ant 1.10.0和Oracle JDK 8.启动该过程的任务类似于:

 <exec executable="${make.executable}" dir="${compile.dir}" failonerror="true"> <arg line="${make.parameters}" /> </exec> 

运行ant的java进程在closures命令行窗口时被正确终止。

这是一个可能的解决方案:

  • 批处理脚本使用名为antPidFile的参数启动Ant。
  • Ant脚本使用Java jps工具来获取运行Ant脚本的java.exe进程的PID。
  • Ant脚本将PID写入antPidFile
  • Ant脚本产生子进程。
  • Ant退出并控制返回到批处理脚本。
  • 批处理脚本将以前的Ant脚本的PID加载到变量中。
  • 批处理脚本使用内置的wmic工具来识别Ant产生的进程。
  • 批处理脚本使用内置的taskkill工具来终止Ant产生的所有子进程(和孙子)。

build.xml文件

 <project name="ant-kill-child-processes" default="run" basedir="."> <target name="run"> <fail unless="antPidFile"/> <exec executable="jps"> <!-- Output the arguments passed to each process's main method. --> <arg value="-m"/> <redirector output="${antPidFile}"> <outputfilterchain> <linecontains> <!-- Match the arguments provided to this Ant script. --> <contains value="Launcher -DantPidFile=${antPidFile}"/> </linecontains> <tokenfilter> <!-- The output of the jps command follows the following pattern: --> <!-- lvmid [ [ classname | JARfilename | "Unknown"] [ arg* ] [ jvmarg* ] ] --> <!-- We want the "lvmid" at the beginning of the line. --> <replaceregex pattern="^(\d+).*$" replace="\1"/> </tokenfilter> </outputfilterchain> </redirector> </exec> <!-- As a test, spawn notepad. It will persist after this Ant script exits. --> <exec executable="notepad" spawn="true"/> </target> </project> 

批处理脚本

 setlocal set DeadAntProcessIdFile=ant-pid.txt call ant "-DantPidFile=%DeadAntProcessIdFile%" rem The Ant script should have written its PID to DeadAntProcessIdFile. set /p DeadAntProcessId=< %DeadAntProcessIdFile% rem Kill any lingering processes created by the Ant script. for /f "skip=1 usebackq" %%h in ( `wmic process where "ParentProcessId=%DeadAntProcessId%" get ProcessId ^| findstr .` ) do taskkill /F /T /PID %%h