Hello I have been frustrated by a change between Ant 1.4.1 and Ant 1.5, and I offer here a patch. First I describe the problem, then my solution.
I had previously used Ant to start my Tomcat engine ("ant start-server"). This was by using a Java task with fork="true". When Ant exited my server was up and running. This kind of task is closely related to my testing process, which would build servlets, restart the server and run my tests. It follows naturally that I should want to use Ant for more general task of starting the server. Unfortunately with the move to 1.5 when the Ant VM terminates it also terminates its child processes, so this functionality has gone. This has frustrated me. My solution has been to add a new option to the Java task. It is called "destroy". I have also added to the manual. The entry for the "destroy" option reads like this: If "true", will destroy the forked process once the Ant VM exits. This is the default setting. However, you may wish to set this to "false" if, for example, your forked Java process starts a Web server which you want to continue running after Ant completes. (Ignored if fork is disabled.) You can see from this that the change is backwards compatible; existing scripts will not break with it. The work also means I added a field to the Execute class, set using a new setDestroy() method. The Java class simply sets the method in the Execute class. The attached diff files are based on 1.5.2beta1. Unfortunately I've not been able to write automatic tests for this since I cannot get the existing ones working ("ant test" fails). As an aside, I'd like to be able to fork an Exec task to, say, start a database from Ant using a shell script. But that's another matter for another day. Hope this is okay and a kindly committer can include this in a future release. Nik -- http://www.workkitchen.org Problems at work? Join the discussion forum
--- ./src/main/org/apache/tools/ant/taskdefs/Execute.java.orig Fri Mar 7 16:27:10 2003 +++ ./src/main/org/apache/tools/ant/taskdefs/Execute.java Fri Mar 7 16:35:22 2003 @@ -93,6 +93,8 @@ private File workingDirectory = null; private Project project = null; private boolean newEnvironment = false; + // Should the process be destroyed when the VM exits? + private boolean destroy = true; /** Controls whether the VM is used to launch commands, where possible */ private boolean useVMLauncher = true; @@ -380,6 +382,15 @@ } /** + * Sets whether the process should be destroyed when its VM exits. + * + * @param d False if you want the process to continue running. + */ + public void setDestroy(boolean d) { + this.destroy = d; + } + + /** * Launch this execution through the VM, where possible, rather than through * the OS's shell. In some cases and operating systems using the shell will * allow the shell to perform additional processing such as associating an @@ -439,8 +450,12 @@ streamHandler.start(); // add the process to the list of those to destroy if the VM exits + // assuming the destroy flag is set // - processDestroyer.add(process); + if (destroy) + { + processDestroyer.add(process); + } if (watchdog != null) { watchdog.start(process);
--- ./docs/manual/CoreTasks/java.html.orig Fri Mar 7 16:57:53 2003 +++ ./docs/manual/CoreTasks/java.html Fri Mar 7 17:05:17 2003 @@ -114,6 +114,16 @@ recommended to use this feature only if fork is enabled.</strong></td> <td align="center" valign="top">No</td> </tr> + <tr> + <td valign="top">destroy</td> + <td valign="top">If "true", will destroy the forked process + once the Ant VM exits. This is the default setting. + However, you may wish to set this to "false" + if, for example, your forked Java process starts a Web server which + you want to continue running after Ant completes. + (Ignored if fork is disabled.)</td> + <td align="center" valign="top">No</td> + </tr> </table> <h3>Parameters specified as nested elements</h3> <h4>arg and jvmarg</h4>
--- ./src/main/org/apache/tools/ant/taskdefs/Java.java.orig Fri Mar 7 16:36:56 2003 +++ ./src/main/org/apache/tools/ant/taskdefs/Java.java Fri Mar 7 16:42:45 2003 @@ -96,6 +96,8 @@ private boolean failOnError = false; private boolean append = false; private Long timeout = null; + // Should we destroy the process when the VM exits? + private boolean destroy = true; /** * Do the execution. @@ -255,6 +257,14 @@ } /** + * If false, keeps the process running after the VM exits. + * Only valid if fork=="true". + */ + public void setDestroy(boolean d) { + this.destroy = d; + } + + /** * Set the command line arguments for the JVM. */ public void setJvmargs(String s) { @@ -484,6 +494,7 @@ exe.setEnvironment(environment); exe.setCommandline(command); + exe.setDestroy(destroy); try { int rc = exe.execute(); if (exe.killedProcess()) {