to allow timeout attribute in <java fork="false"> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272235 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,7 +1,7 @@ | |||||
| /* | /* | ||||
| * The Apache Software License, Version 1.1 | * The Apache Software License, Version 1.1 | ||||
| * | * | ||||
| * Copyright (c) 2000-2001 The Apache Software Foundation. All rights | |||||
| * Copyright (c) 2000-2002 The Apache Software Foundation. All rights | |||||
| * reserved. | * reserved. | ||||
| * | * | ||||
| * Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
| @@ -55,6 +55,8 @@ | |||||
| package org.apache.tools.ant.taskdefs; | package org.apache.tools.ant.taskdefs; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.util.TimeoutObserver; | |||||
| import org.apache.tools.ant.util.Watchdog; | |||||
| /** | /** | ||||
| * Destroys a process running for too long. | * Destroys a process running for too long. | ||||
| @@ -72,15 +74,13 @@ import org.apache.tools.ant.BuildException; | |||||
| * @author thomas.haas@softwired-inc.com | * @author thomas.haas@softwired-inc.com | ||||
| * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
| * @see Execute | * @see Execute | ||||
| * @see org.apache.tools.ant.util.Watchdog | |||||
| */ | */ | ||||
| public class ExecuteWatchdog implements Runnable { | |||||
| public class ExecuteWatchdog implements TimeoutObserver { | |||||
| /** the process to execute and watch for duration */ | /** the process to execute and watch for duration */ | ||||
| private Process process; | private Process process; | ||||
| /** timeout duration. Once the process running time exceeds this it should be killed */ | |||||
| private int timeout; | |||||
| /** say whether or not the watchog is currently monitoring a process */ | /** say whether or not the watchog is currently monitoring a process */ | ||||
| private boolean watch = false; | private boolean watch = false; | ||||
| @@ -90,16 +90,17 @@ public class ExecuteWatchdog implements Runnable { | |||||
| /** say whether or not the process was killed due to running overtime */ | /** say whether or not the process was killed due to running overtime */ | ||||
| private boolean killedProcess = false; | private boolean killedProcess = false; | ||||
| /** will tell us whether timeout has occured */ | |||||
| private Watchdog watchdog; | |||||
| /** | /** | ||||
| * Creates a new watchdog with a given timeout. | * Creates a new watchdog with a given timeout. | ||||
| * | * | ||||
| * @param timeout the timeout for the process in milliseconds. It must be greather than 0. | * @param timeout the timeout for the process in milliseconds. It must be greather than 0. | ||||
| */ | */ | ||||
| public ExecuteWatchdog(int timeout) { | public ExecuteWatchdog(int timeout) { | ||||
| if (timeout < 1) { | |||||
| throw new IllegalArgumentException("timeout lesser than 1."); | |||||
| } | |||||
| this.timeout = timeout; | |||||
| watchdog = new Watchdog(timeout); | |||||
| watchdog.addTimeoutObserver(this); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -119,43 +120,28 @@ public class ExecuteWatchdog implements Runnable { | |||||
| this.killedProcess = false; | this.killedProcess = false; | ||||
| this.watch = true; | this.watch = true; | ||||
| this.process = process; | this.process = process; | ||||
| final Thread thread = new Thread(this, "WATCHDOG"); | |||||
| thread.setDaemon(true); | |||||
| thread.start(); | |||||
| watchdog.start(); | |||||
| } | } | ||||
| /** | /** | ||||
| * Stops the watcher. It will notify all threads possibly waiting on this object. | * Stops the watcher. It will notify all threads possibly waiting on this object. | ||||
| */ | */ | ||||
| public synchronized void stop() { | public synchronized void stop() { | ||||
| watchdog.stop(); | |||||
| watch = false; | watch = false; | ||||
| notifyAll(); | |||||
| process = null; | |||||
| } | } | ||||
| /** | /** | ||||
| * Watches the process and terminates it, if it runs for to long. | |||||
| * Called after watchdog has finished. | |||||
| */ | */ | ||||
| public synchronized void run() { | |||||
| public void timeoutOccured(Watchdog w) { | |||||
| try { | try { | ||||
| // This isn't a Task, don't have a Project object to log. | |||||
| // project.log("ExecuteWatchdog: timeout = "+timeout+" msec", Project.MSG_VERBOSE); | |||||
| final long until = System.currentTimeMillis() + timeout; | |||||
| long now; | |||||
| while (watch && until > (now = System.currentTimeMillis())) { | |||||
| try { | |||||
| wait(until - now); | |||||
| } catch (InterruptedException e) {} | |||||
| } | |||||
| // if we are here, either someone stopped the watchdog, | |||||
| // we are on timeout and the process must be killed, or | |||||
| // we are on timeout and the process has already stopped. | |||||
| try { | try { | ||||
| // We must check if the process was not stopped | // We must check if the process was not stopped | ||||
| // before being here | // before being here | ||||
| process.exitValue(); | process.exitValue(); | ||||
| } catch (IllegalThreadStateException e){ | |||||
| } catch (IllegalThreadStateException itse){ | |||||
| // the process is not terminated, if this is really | // the process is not terminated, if this is really | ||||
| // a timeout and not a manual stop then kill it. | // a timeout and not a manual stop then kill it. | ||||
| if (watch){ | if (watch){ | ||||
| @@ -163,7 +149,7 @@ public class ExecuteWatchdog implements Runnable { | |||||
| process.destroy(); | process.destroy(); | ||||
| } | } | ||||
| } | } | ||||
| } catch(Exception e) { | |||||
| } catch (Exception e) { | |||||
| caught = e; | caught = e; | ||||
| } finally { | } finally { | ||||
| cleanUp(); | cleanUp(); | ||||
| @@ -0,0 +1,70 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2002 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.util; | |||||
| /** | |||||
| * Interface for classes that want to be notified by Watchdog. | |||||
| * | |||||
| * @since 1.5 | |||||
| * | |||||
| * @see org.apache.tools.ant.util.Watchdog | |||||
| * | |||||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public interface TimeoutObserver { | |||||
| void timeoutOccured(Watchdog w); | |||||
| } | |||||
| @@ -0,0 +1,124 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2002 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.util; | |||||
| import java.util.Enumeration; | |||||
| import java.util.Vector; | |||||
| /** | |||||
| * Generalization of <code>ExecuteWatchdog</code> | |||||
| * | |||||
| * @since Ant 1.5 | |||||
| * | |||||
| * @see org.apache.tools.ant.taskdefs.ExecuteWatchdog | |||||
| * | |||||
| * @author <a href="stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author thomas.haas@softwired-inc.com | |||||
| * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | |||||
| */ | |||||
| public class Watchdog implements Runnable { | |||||
| private Vector observers = new Vector(1); | |||||
| private long timeout = -1; | |||||
| private boolean stopped = false; | |||||
| public Watchdog(long timeout) { | |||||
| if (timeout < 1) { | |||||
| throw new IllegalArgumentException("timeout lesser than 1."); | |||||
| } | |||||
| this.timeout = timeout; | |||||
| } | |||||
| public void addTimeoutObserver(TimeoutObserver to) { | |||||
| observers.addElement(to); | |||||
| } | |||||
| public void removeTimeoutObserver(TimeoutObserver to) { | |||||
| observers.removeElement(to); | |||||
| } | |||||
| protected final void fireTimeoutOccured() { | |||||
| Enumeration enum = observers.elements(); | |||||
| while (enum.hasMoreElements()) { | |||||
| ((TimeoutObserver) enum.nextElement()).timeoutOccured(this); | |||||
| } | |||||
| } | |||||
| public synchronized void start() { | |||||
| stopped = false; | |||||
| Thread t = new Thread(this, "WATCHDOG"); | |||||
| t.setDaemon(true); | |||||
| t.start(); | |||||
| } | |||||
| public synchronized void stop() { | |||||
| stopped = true; | |||||
| notifyAll(); | |||||
| } | |||||
| public synchronized void run() { | |||||
| final long until = System.currentTimeMillis() + timeout; | |||||
| long now; | |||||
| while (!stopped && until > (now = System.currentTimeMillis())) { | |||||
| try { | |||||
| wait(until - now); | |||||
| } catch (InterruptedException e) {} | |||||
| } | |||||
| if (!stopped) { | |||||
| fireTimeoutOccured(); | |||||
| } | |||||
| } | |||||
| } | |||||