ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject cvs commit: jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs ExecuteJavaTest.java TimeProcess.java ExecuteWatchdogTest.java
Date Fri, 05 Apr 2002 12:56:34 GMT
bodewig     02/04/05 04:56:34

  Modified:    src/main/org/apache/tools/ant/taskdefs ExecTask.java
                        ExecuteJava.java ExecuteWatchdog.java Java.java
               src/main/org/apache/tools/ant/util TimeoutObserver.java
                        Watchdog.java
               src/testcases/org/apache/tools/ant/taskdefs
                        ExecuteWatchdogTest.java
  Added:       src/testcases/org/apache/tools/ant/taskdefs
                        ExecuteJavaTest.java TimeProcess.java
  Log:
  timeout support for <java>
  
  PR: 5299
  
  Revision  Changes    Path
  1.31      +3 -3      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java
  
  Index: ExecTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecTask.java,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -r1.30 -r1.31
  --- ExecTask.java	5 Apr 2002 09:28:54 -0000	1.30
  +++ ExecTask.java	5 Apr 2002 12:56:34 -0000	1.31
  @@ -88,7 +88,7 @@
       private File dir;
       protected boolean failOnError = false;
       protected boolean newEnvironment = false;
  -    private Integer timeout = null;
  +    private Long timeout = null;
       private Environment env = new Environment();
       protected Commandline cmdl = new Commandline();
       private FileOutputStream fos = null;
  @@ -104,7 +104,7 @@
       /**
        * Timeout in milliseconds after which the process will be killed.
        */
  -    public void setTimeout(Integer value) {
  +    public void setTimeout(Long value) {
           timeout = value;
       }
   
  @@ -377,7 +377,7 @@
           if (timeout == null) {
             return null;
           }
  -        return new ExecuteWatchdog(timeout.intValue());
  +        return new ExecuteWatchdog(timeout.longValue());
       }
   
       /**
  
  
  
  1.19      +87 -15    jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
  
  Index: ExecuteJava.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- ExecuteJava.java	10 Jan 2002 13:59:31 -0000	1.18
  +++ ExecuteJava.java	5 Apr 2002 12:56:34 -0000	1.19
  @@ -1,7 +1,7 @@
   /*
    * 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.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -62,21 +62,28 @@
   import org.apache.tools.ant.types.Commandline;
   import org.apache.tools.ant.types.CommandlineJava;
   import org.apache.tools.ant.types.Path;
  +import org.apache.tools.ant.util.TimeoutObserver;
  +import org.apache.tools.ant.util.Watchdog;
   
   import java.lang.reflect.InvocationTargetException;
   import java.lang.reflect.Method;
   import java.io.PrintStream;
   
  -/*
  +/**
    *
    * @author thomas.haas@softwired-inc.com
    * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
    */
  -public class ExecuteJava {
  +public class ExecuteJava implements Runnable, TimeoutObserver {
   
       private Commandline javaCommand = null;
       private Path classpath = null;
       private CommandlineJava.SysProperties sysProperties = null;
  +    private Method main = null;
  +    private Long timeout = null;
  +    private Throwable caught = null;
  +    private boolean timedOut = false;
  +    private Thread thread = null;
   
       public void setJavaCommand(Commandline javaCommand) {
           this.javaCommand = javaCommand;
  @@ -99,9 +106,15 @@
       public void setOutput(PrintStream out) {
       }
   
  +    /**
  +     * @since 1.19, Ant 1.5
  +     */
  +    public void setTimeout(Long timeout) {
  +        this.timeout = timeout;
  +    }
  +
       public void execute(Project project) throws BuildException{
           final String classname = javaCommand.getExecutable();
  -        final Object[] argument = { javaCommand.getArguments() };
   
           AntClassLoader loader = null; 
           try {
  @@ -120,21 +133,41 @@
                   target = loader.forceLoadClass(classname);
                   AntClassLoader.initializeClass(target);
               }
  -            final Method main = target.getMethod("main", param);
  -            main.invoke(null, argument);
  +            main = target.getMethod("main", param);
  +
  +            if (timeout == null) {
  +                run();
  +            } else {
  +                thread = new Thread(this, "ExecuteJava");
  +                Watchdog w = new Watchdog(timeout.longValue());
  +                w.addTimeoutObserver(this);
  +                synchronized (this) {
  +                    thread.start();
  +                    w.start();
  +                    try {
  +                        wait();
  +                    } catch (InterruptedException e) {}
  +                    if (timedOut) {
  +                        project.log("Timeout: killed the sub-process",
  +                                    Project.MSG_WARN); 
  +                    } else {
  +                        thread = null;
  +                        w.stop();
  +                    }
  +                }
  +            }
  +
  +            if (caught != null) {
  +                throw caught;
  +            }
  +
           } catch (NullPointerException e) {
               throw new BuildException("Could not find main() method in " + classname);
           } catch (ClassNotFoundException e) {
               throw new BuildException("Could not find " + classname + ". Make sure you have
it in your classpath");
  -        } catch (InvocationTargetException e) {
  -            Throwable t = e.getTargetException();
  -            if (!(t instanceof SecurityException)) {
  -                throw new BuildException(t);
  -            }
  -            else {
  -                throw (SecurityException)t;
  -            }
  -        } catch (Exception e) {
  +        } catch (SecurityException e) {
  +            throw e;
  +        } catch (Throwable e) {
               throw new BuildException(e);
           } finally {
               if (loader != null) {
  @@ -145,5 +178,44 @@
                   sysProperties.restoreSystem();
               }
           }
  +    }
  +
  +    /**
  +     * @since 1.19, Ant 1.5
  +     */
  +    public void run() {
  +        final Object[] argument = { javaCommand.getArguments() };
  +        try {
  +            main.invoke(null, argument);
  +        } catch (InvocationTargetException e) {
  +            Throwable t = e.getTargetException();
  +            if (!(t instanceof InterruptedException)) {
  +                caught = t;
  +            } /* else { swallow, probably due to timeout } */
  +        } catch (Throwable t) {
  +            caught = t;
  +        } finally {
  +            synchronized (this) {
  +                notifyAll();
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @since 1.19, Ant 1.5
  +     */
  +    public synchronized void timeoutOccured(Watchdog w) {
  +        if (thread != null) {
  +            timedOut = true;
  +            thread.interrupt();
  +        }
  +        notifyAll();
  +    }
  +
  +    /**
  +     * @since 1.19, Ant 1.5
  +     */
  +    public boolean killedProcess() {
  +        return timedOut;
       }
   }
  
  
  
  1.8       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java
  
  Index: ExecuteWatchdog.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/ExecuteWatchdog.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ExecuteWatchdog.java	5 Apr 2002 10:13:02 -0000	1.7
  +++ ExecuteWatchdog.java	5 Apr 2002 12:56:34 -0000	1.8
  @@ -98,7 +98,7 @@
        *
        * @param timeout the timeout for the process in milliseconds. It must be greather
than 0.
        */
  -    public ExecuteWatchdog(int timeout) {
  +    public ExecuteWatchdog(long timeout) {
           watchdog = new Watchdog(timeout);
           watchdog.addTimeoutObserver(this);
       }
  
  
  
  1.37      +32 -3     jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Java.java
  
  Index: Java.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Java.java,v
  retrieving revision 1.36
  retrieving revision 1.37
  diff -u -r1.36 -r1.37
  --- Java.java	5 Apr 2002 09:28:54 -0000	1.36
  +++ Java.java	5 Apr 2002 12:56:34 -0000	1.37
  @@ -91,6 +91,7 @@
       private PrintStream outStream = null;
       private boolean failOnError = false;
       private boolean append = false;
  +    private Long timeout = null;
       
       /**
        * Do the execution.
  @@ -309,6 +310,15 @@
           this.append = append;
       }
   
  +    /**
  +     * Timeout in milliseconds after which the process will be killed.
  +     *
  +     * @since 1.37, Ant 1.5
  +     */
  +    public void setTimeout(Long value) {
  +        timeout = value;
  +    }
  +
       protected void handleOutput(String line) {
           if (outStream != null) {
               outStream.println(line);
  @@ -336,6 +346,7 @@
           exe.setJavaCommand(command.getJavaCommand());
           exe.setClasspath(command.getClasspath());
           exe.setSystemProperties(command.getSystemProperties());
  +        exe.setTimeout(timeout);
           if (out != null) {
               try {
                   outStream = 
  @@ -366,10 +377,11 @@
               if (out == null) {
                   exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO,
                                                          Project.MSG_WARN), 
  -                                  null);
  +                                  createWatchdog());
               } else {
                   fos = new FileOutputStream(out.getAbsolutePath(), append);
  -                exe = new Execute(new PumpStreamHandler(fos), null);
  +                exe = new Execute(new PumpStreamHandler(fos),
  +                                  createWatchdog());
               }
               
               exe.setAntRun(project);
  @@ -395,7 +407,11 @@
   
               exe.setCommandline(command);
               try {
  -                return exe.execute();
  +                int rc = exe.execute();
  +                if(exe.killedProcess()) {
  +                    log("Timeout: killed the sub-process",Project.MSG_WARN); 
  +                }
  +                return rc;
               } catch (IOException e) {
                   throw new BuildException(e, location);
               }
  @@ -427,4 +443,17 @@
       public void clearArgs() {
           cmdl.clearJavaArgs();
       }
  +
  +    /**
  +     * Create the Watchdog to kill a runaway process.
  +     *
  +     * @since 1.37, Ant 1.5
  +     */
  +    protected ExecuteWatchdog createWatchdog() throws BuildException {
  +        if (timeout == null) {
  +          return null;
  +        }
  +        return new ExecuteWatchdog(timeout.longValue());
  +    }
  +
   }
  
  
  
  1.2       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/util/TimeoutObserver.java
  
  Index: TimeoutObserver.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/TimeoutObserver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TimeoutObserver.java	5 Apr 2002 10:13:02 -0000	1.1
  +++ TimeoutObserver.java	5 Apr 2002 12:56:34 -0000	1.2
  @@ -57,7 +57,7 @@
   /**
    * Interface for classes that want to be notified by Watchdog.
    *
  - * @since 1.5
  + * @since Ant 1.5
    *
    * @see org.apache.tools.ant.util.Watchdog
    *
  
  
  
  1.2       +1 -1      jakarta-ant/src/main/org/apache/tools/ant/util/Watchdog.java
  
  Index: Watchdog.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/main/org/apache/tools/ant/util/Watchdog.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Watchdog.java	5 Apr 2002 10:13:02 -0000	1.1
  +++ Watchdog.java	5 Apr 2002 12:56:34 -0000	1.2
  @@ -113,7 +113,7 @@
           long now;
           while (!stopped && until > (now = System.currentTimeMillis())) {
               try {
  -                    wait(until - now);
  +                wait(until - now);
               } catch (InterruptedException e) {}
           }
           if (!stopped) {
  
  
  
  1.10      +7 -17     jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java
  
  Index: ExecuteWatchdogTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/ExecuteWatchdogTest.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ExecuteWatchdogTest.java	4 Mar 2002 08:49:35 -0000	1.9
  +++ ExecuteWatchdogTest.java	5 Apr 2002 12:56:34 -0000	1.10
  @@ -95,13 +95,13 @@
               classpath = System.getProperty("java.class.path");
           }
   
  -                // JDK 1.1 needs classes.zip in -classpath argument
  -                if (Project.getJavaVersion() == Project.JAVA_1_1) {
  -                    classpath +=   File.pathSeparator
  -                                 + System.getProperty("java.home")
  -                                 + File.separator + "lib"
  -                                 + File.separator + "classes.zip";
  -                }
  +        // JDK 1.1 needs classes.zip in -classpath argument
  +        if (Project.getJavaVersion() == Project.JAVA_1_1) {
  +            classpath +=   File.pathSeparator
  +                + System.getProperty("java.home")
  +                + File.separator + "lib"
  +                + File.separator + "classes.zip";
  +        }
   
           return classpath;
       }
  @@ -196,15 +196,5 @@
           // process should be dead and well finished
           assertEquals(0, process.exitValue());
           assertTrue("process should not have been killed", !watchdog.killedProcess());
  -    }
  -
  -    public static class TimeProcess {
  -        public static void main(String[] args) throws Exception {
  -            int time = Integer.parseInt(args[0]);
  -            if (time < 1) {
  -                throw new IllegalArgumentException("Invalid time: " + time);
  -            }
  -            Thread.sleep(time);
  -        }
       }
   }
  
  
  
  1.1                  jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/ExecuteJavaTest.java
  
  Index: ExecuteJavaTest.java
  ===================================================================
  /*
   * 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.taskdefs;
  
  import org.apache.tools.ant.Project;
  import org.apache.tools.ant.types.Path;
  import org.apache.tools.ant.types.Commandline;
  
  import java.io.File;
  
  import junit.framework.TestCase;
  
  /**
   * Simple testcase for the ExecuteJava class - mostly stolen from
   * ExecuteWatchdogTest.
   *
   * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   */
  public class ExecuteJavaTest extends TestCase {
  
      private final static int TIME_OUT = 5000;
  
      private final static int CLOCK_ERROR=200;
      private final static int TIME_OUT_TEST=TIME_OUT-CLOCK_ERROR;
      
      private ExecuteJava ej;
      private Project project;
  
      public ExecuteJavaTest(String name) {
          super(name);
      }
  
      protected void setUp(){
          ej = new ExecuteJava();
          ej.setTimeout(new Long(TIME_OUT));
          project = new Project();
          project.setBasedir(".");
          ej.setClasspath(new Path(project, getTestClassPath()));
      }
  
      private Commandline getCommandline(int timetorun) throws Exception {
          Commandline cmd = new Commandline();
          cmd.setExecutable(TimeProcess.class.getName());
          cmd.createArgument().setValue(String.valueOf(timetorun));
          return cmd;
      }
  
      public void testNoTimeOut() throws Exception {
          Commandline cmd = getCommandline(TIME_OUT/2);
          ej.setJavaCommand(cmd);
          ej.execute(project);
          assertTrue("process should not have been killed", !ej.killedProcess());
      }
  
      // test that the watchdog ends the process
      public void testTimeOut() throws Exception {
          Commandline cmd = getCommandline(TIME_OUT*2);
          ej.setJavaCommand(cmd);
          long now = System.currentTimeMillis();
          ej.execute(project);
          long elapsed = System.currentTimeMillis() - now;
          assertTrue("process should have been killed", ej.killedProcess());
  
          assertTrue("elapse time of "+elapsed
                     +" ms is less than timeout value of "+TIME_OUT_TEST+" ms", 
                     elapsed >= TIME_OUT_TEST);
          assertTrue("elapse time of "+elapsed
                     +" ms is greater than run value of "+(TIME_OUT*2)+" ms", 
                     elapsed < TIME_OUT*2);
      }
  
  
      /**
       * Dangerous method to obtain the classpath for the test. This is
       * severely tighted to the build.xml properties.
       */
      private static String getTestClassPath(){
          String classpath = System.getProperty("build.tests");
          if (classpath == null) {
              System.err.println("WARNING: 'build.tests' property is not available !");
              classpath = System.getProperty("java.class.path");
          }
  
          // JDK 1.1 needs classes.zip in -classpath argument
          if (Project.getJavaVersion() == Project.JAVA_1_1) {
              classpath +=   File.pathSeparator
                  + System.getProperty("java.home")
                  + File.separator + "lib"
                  + File.separator + "classes.zip";
          }
  
          return classpath;
      }
  
  }
  
  
  
  1.1                  jakarta-ant/src/testcases/org/apache/tools/ant/taskdefs/TimeProcess.java
  
  Index: TimeProcess.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-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.taskdefs;
  
  /**
   * Helper class for ExecuteWatchdogTest and ExecuteJavaTest.
   *
   * <p>Used to be an inner class of ExecuteWatchdogTest.
   *
   * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a>
   */
  public class TimeProcess {
      public static void main(String[] args) throws Exception {
          int time = Integer.parseInt(args[0]);
          if (time < 1) {
              throw new IllegalArgumentException("Invalid time: " + time);
          }
          Thread.sleep(time);
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message