Search code examples
antcopy-pasteshutdown-hook

Ant build shutdown - Ctrl C


I have a set of ant tasks that I use to run my test suite, occasionally one of those tests will freeze and my entire test suite will hang. I added a shutdown handler so when I hit Ctrl+C ant will shutdown gracefully and give me a report with the final test marked as not run. (This is important because these are integration tests and can run for hours) This works great except for on Windows where my shutdown hook is not being called. Is there a way I can get ant to respond to any kind of input and do a graceful shutdown?


Solution

  • It seems this is a long-running known issue.

    The problem is that on Windows the Ant Ctrl+C is, as you have observed, not propagated to the child VMs. Things you might consider:

    • Break up the test into smaller pieces and use a timeout to kill anything that hangs. This will limit the data lost to the one test that hangs.
    • In your test run, add a 'listener' thread that waits for a shutdown 'signal' (perhaps the presence of a flag file) and arrange for that signal to be set by Ant, on command from the console, if hang is detected.

    This appears complex, but might be worth a shot. You'd need to combine the Ant parallel and input tasks to run the tests in one thread, and wait for input from the console in a second thread. When abort is chosen, the signal file is written, this is detected in the test run 'listener', causing it to terminate. Any other input would lead to clean termination of the run. The problem with this is that, if the test completes successfully, you're left with Ant waiting for user input, but you could put an overall timeout in place for that. (I've not given an example of how the test run code might detect the signal file.)

    Psuedo-Ant:

    <property name="signal.abort" value="stop.txt" />
    <target name="runner">
        <delete file="${signal.abort}" />
        <parallel timeout="86400000">
            <sequential>
    
                <!-- run tests here -->
    
            </sequential>
            <sequential>
                <input validargs="y,n"
                       message="Abort the test (y/n)?"
                       addproperty="abort.test" />
                <condition property="do.abort">
                    <equals arg1="y" arg2="${abort.test}"/>
                </condition>
                <ant target="terminator" />
            </sequential>
        </parallel>
    </target>
    
    <target name="terminator" if="do.abort">
        <echo message="abort" file="${signal.abort}" />
    </target>