Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache Ant: Terminate process started by <exec> when ant process is terminated

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.

like image 265
Cybran Avatar asked Oct 30 '22 14:10

Cybran


1 Answers

Here's a possible solution:

  • A batch script launches Ant with an argument named antPidFile.
  • The Ant script uses the Java jps tool to get the PID of the java.exe process running the Ant script.
  • The Ant script writes the PID to antPidFile.
  • The Ant script spawns child processes.
  • Ant exits and control returns to the batch script.
  • The batch script loads the PID of the former Ant script into a variable.
  • The batch script uses the built-in wmic tool to identify processes spawned by Ant.
  • The batch script uses the built-in taskkill tool to terminate all of the child processes (and grandchildren) spawned by 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>

Batch Script

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
like image 99
Chad Nouis Avatar answered Nov 11 '22 12:11

Chad Nouis