I have an ant task which executes a lengthy build operation using <exec>
. Ant is started by a batch file from the windows command line. If I terminate the ant task by closing the window, the process started by <exec>
keeps running. How can I achieve to terminate the spawned process when the ant process itself is terminated?
Ant 1.10.0 is used on Windows 7 x64 with Oracle JDK 8. The task starting the process is similar to:
<exec executable="${make.executable}" dir="${compile.dir}" failonerror="true">
<arg line="${make.parameters}" />
</exec>
The java
process running ant is properly terminated when closing the command line window.
Here's a possible solution:
antPidFile
.jps
tool to get the PID of the java.exe
process running the Ant script.antPidFile
.wmic
tool to identify processes spawned by Ant.taskkill
tool to terminate all of the child processes (and grandchildren) spawned by Ant.<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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With