Clover coverage report - Ant Coverage
Coverage timestamp: Tue Apr 8 2003 20:43:55 EST
file stats: LOC: 566   Methods: 39
NCLOC: 288   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Java.java 52% 56.8% 38.5% 52.3%
 1   
 /*
 2   
  * The Apache Software License, Version 1.1
 3   
  *
 4   
  * Copyright (c) 2000-2003 The Apache Software Foundation.  All rights 
 5   
  * reserved.
 6   
  *
 7   
  * Redistribution and use in source and binary forms, with or without
 8   
  * modification, are permitted provided that the following conditions
 9   
  * are met:
 10   
  *
 11   
  * 1. Redistributions of source code must retain the above copyright
 12   
  *    notice, this list of conditions and the following disclaimer.
 13   
  *
 14   
  * 2. Redistributions in binary form must reproduce the above copyright
 15   
  *    notice, this list of conditions and the following disclaimer in
 16   
  *    the documentation and/or other materials provided with the
 17   
  *    distribution.
 18   
  *
 19   
  * 3. The end-user documentation included with the redistribution, if
 20   
  *    any, must include the following acknowlegement:
 21   
  *       "This product includes software developed by the
 22   
  *        Apache Software Foundation (http://www.apache.org/)."
 23   
  *    Alternately, this acknowlegement may appear in the software itself,
 24   
  *    if and wherever such third-party acknowlegements normally appear.
 25   
  *
 26   
  * 4. The names "Ant" and "Apache Software
 27   
  *    Foundation" must not be used to endorse or promote products derived
 28   
  *    from this software without prior written permission. For written
 29   
  *    permission, please contact apache@apache.org.
 30   
  *
 31   
  * 5. Products derived from this software may not be called "Apache"
 32   
  *    nor may "Apache" appear in their names without prior written
 33   
  *    permission of the Apache Group.
 34   
  *
 35   
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 36   
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 37   
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 38   
  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 39   
  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 40   
  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 41   
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 42   
  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 43   
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 44   
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 45   
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 46   
  * SUCH DAMAGE.
 47   
  * ====================================================================
 48   
  *
 49   
  * This software consists of voluntary contributions made by many
 50   
  * individuals on behalf of the Apache Software Foundation.  For more
 51   
  * information on the Apache Software Foundation, please see
 52   
  * <http://www.apache.org/>.
 53   
  */
 54   
 
 55   
 package org.apache.tools.ant.taskdefs;
 56   
 
 57   
 import java.io.File;
 58   
 import java.io.IOException;
 59   
 import java.util.Vector;
 60   
 import org.apache.tools.ant.BuildException;
 61   
 import org.apache.tools.ant.ExitException;
 62   
 import org.apache.tools.ant.Project;
 63   
 import org.apache.tools.ant.Task;
 64   
 import org.apache.tools.ant.types.Commandline;
 65   
 import org.apache.tools.ant.types.CommandlineJava;
 66   
 import org.apache.tools.ant.types.Environment;
 67   
 import org.apache.tools.ant.types.Path;
 68   
 import org.apache.tools.ant.types.Reference;
 69   
 
 70   
 /**
 71   
  * Launcher for Java applications. Allows use of
 72   
  * the same JVM for the called application thus resulting in much
 73   
  * faster operation.
 74   
  *
 75   
  * @author Stefano Mazzocchi 
 76   
  *         <a href="mailto:stefano@apache.org">stefano@apache.org</a>
 77   
  * @author Stefan Bodewig
 78   
  *
 79   
  * @since Ant 1.1
 80   
  *
 81   
  * @ant.task category="java"
 82   
  */
 83   
 public class Java extends Task {
 84   
 
 85   
     private CommandlineJava cmdl = new CommandlineJava();
 86   
     private Environment env = new Environment();
 87   
     private boolean fork = false;
 88   
     private boolean newEnvironment = false;
 89   
     private File dir = null;
 90   
     private boolean failOnError = false;
 91   
     private boolean append = false;
 92   
     private Long timeout = null;
 93   
     private Redirector redirector = new Redirector(this);
 94   
     /**
 95   
      * Do the execution.
 96   
      */
 97  17
     public void execute() throws BuildException {
 98  17
         File savedDir = dir;
 99   
 
 100  17
         int err = -1;
 101  17
         try {
 102  ?
             if ((err = executeJava()) != 0) { 
 103  9
                 if (failOnError) {
 104  8
                     throw new BuildException("Java returned: " + err, getLocation());
 105   
                 } else {
 106  1
                     log("Java Result: " + err, Project.MSG_ERR);
 107   
                 }
 108   
             }
 109   
         } finally {
 110  17
             dir = savedDir;
 111   
         }
 112   
     }
 113   
 
 114   
     /**
 115   
      * Do the execution and return a return code.
 116   
      *
 117   
      * @return the return code from the execute java class if it was
 118   
      * executed in a separate VM (fork = "yes").
 119   
      */
 120  17
     public int executeJava() throws BuildException {
 121  17
         String classname = cmdl.getClassname();
 122  17
         if (classname == null && cmdl.getJar() == null) {
 123  1
             throw new BuildException("Classname must not be null.");
 124   
         }
 125   
 
 126  16
         if (!fork && cmdl.getJar() != null){
 127  1
             throw new BuildException("Cannot execute a jar in non-forked mode."
 128   
                                      + " Please set fork='true'. ");
 129   
         }
 130   
 
 131  15
         if (fork) {
 132  10
             log(cmdl.describeCommand(), Project.MSG_VERBOSE);
 133   
         } else {
 134  5
             if (cmdl.getVmCommand().size() > 1) {
 135  0
                 log("JVM args ignored when same JVM is used.", 
 136   
                     Project.MSG_WARN);
 137   
             }
 138  5
             if (dir != null) {
 139  0
                 log("Working directory ignored when same JVM is used.", 
 140   
                     Project.MSG_WARN);
 141   
             }
 142   
 
 143  5
             if (newEnvironment || null != env.getVariables()) {
 144  0
                 log("Changes to environment variables are ignored when same "
 145   
                     + "JVM is used.", Project.MSG_WARN);
 146   
             }
 147   
 
 148  5
             log("Running in same VM " + cmdl.describeJavaCommand(), 
 149   
                 Project.MSG_VERBOSE);
 150   
         }
 151   
         
 152  15
         try {
 153  15
             if (fork) {
 154  10
                 return run(cmdl.getCommandline());
 155   
             } else {
 156  5
                 try {
 157  5
                     run(cmdl);
 158  3
                     return 0;
 159   
                 } catch (ExitException ex) {
 160  0
                     return ex.getStatus();
 161   
                 }
 162   
             }
 163   
         } catch (BuildException e) {
 164  2
             if (failOnError) {
 165  1
                 throw e;
 166   
             } else {
 167  1
                 log(e.getMessage(), Project.MSG_ERR);
 168  1
                 return 0;
 169   
             }
 170   
         } catch (Throwable t) {
 171  0
             if (failOnError) {
 172  0
                 throw new BuildException(t);
 173   
             } else {
 174  0
                 log(t.getMessage(), Project.MSG_ERR);
 175  0
                 return 0;
 176   
             }
 177   
         }
 178   
     }
 179   
 
 180   
     /**
 181   
      * Set the classpath to be used when running the Java class
 182   
      * 
 183   
      * @param s an Ant Path object containing the classpath.
 184   
      */
 185  12
     public void setClasspath(Path s) {
 186  12
         createClasspath().append(s);
 187   
     }
 188   
     
 189   
     /**
 190   
      * Adds a path to the classpath.
 191   
      */
 192  14
     public Path createClasspath() {
 193  14
         return cmdl.createClasspath(getProject()).createPath();
 194   
     }
 195   
 
 196   
     /**
 197   
      * Classpath to use, by reference.
 198   
      */
 199  0
     public void setClasspathRef(Reference r) {
 200  0
         createClasspath().setRefid(r);
 201   
     }
 202   
 
 203   
     /**
 204   
      * The location of the JAR file to execute.
 205   
      */
 206  3
     public void setJar(File jarfile) throws BuildException {
 207  3
         if (cmdl.getClassname() != null){
 208  1
             throw new BuildException("Cannot use 'jar' and 'classname' "
 209   
                                      + "attributes in same command.");
 210   
         }
 211  2
         cmdl.setJar(jarfile.getAbsolutePath());
 212   
     }
 213   
 
 214   
     /**
 215   
      * Sets the Java class to execute.
 216   
      */
 217  17
     public void setClassname(String s) throws BuildException {
 218  17
         if (cmdl.getJar() != null){
 219  1
             throw new BuildException("Cannot use 'jar' and 'classname' "
 220   
                                      + "attributes in same command");
 221   
         }
 222  16
         cmdl.setClassname(s);
 223   
     }
 224   
 
 225   
     /**
 226   
      * Deprecated: use nested arg instead.
 227   
      * Set the command line arguments for the class.
 228   
      * @ant.attribute ignore="true"
 229   
      */
 230  0
     public void setArgs(String s) {
 231  0
         log("The args attribute is deprecated. " +
 232   
             "Please use nested arg elements.",
 233   
             Project.MSG_WARN);
 234  0
         cmdl.createArgument().setLine(s);
 235   
     }
 236   
 
 237   
     /**
 238   
      * Adds a command-line argument.
 239   
      */
 240  39
     public Commandline.Argument createArg() {
 241  39
         return cmdl.createArgument();
 242   
     }
 243   
 
 244   
     /**
 245   
      * If true, execute in a new VM.
 246   
      */
 247  11
     public void setFork(boolean s) {
 248  11
         this.fork = s;
 249   
     }
 250   
 
 251   
     /**
 252   
      * Set the command line arguments for the JVM.
 253   
      */
 254  0
     public void setJvmargs(String s) {
 255  0
         log("The jvmargs attribute is deprecated. " +
 256   
             "Please use nested jvmarg elements.",
 257   
             Project.MSG_WARN);
 258  0
         cmdl.createVmArgument().setLine(s);
 259   
     }
 260   
         
 261   
     /**
 262   
      * Adds a JVM argument.
 263   
      */
 264  0
     public Commandline.Argument createJvmarg() {
 265  0
         return cmdl.createVmArgument();
 266   
     }
 267   
 
 268   
     /**
 269   
      * Set the command used to start the VM (only if not forking).
 270   
      */
 271  0
     public void setJvm(String s) {
 272  0
         cmdl.setVm(s);
 273   
     }
 274   
         
 275   
     /**
 276   
      * Adds a system property.
 277   
      */
 278  0
     public void addSysproperty(Environment.Variable sysp) {
 279  0
         cmdl.addSysproperty(sysp);
 280   
     }
 281   
 
 282   
     /**
 283   
      * If true, then fail if the command exits with a
 284   
      * returncode other than 0
 285   
      */
 286  9
     public void setFailonerror(boolean fail) {
 287  9
         failOnError = fail;
 288   
     }
 289   
 
 290   
     /**
 291   
      * The working directory of the process
 292   
      */
 293  6
     public void setDir(File d) {
 294  6
         this.dir = d;
 295   
     }
 296   
 
 297   
     /**
 298   
      * File the output of the process is redirected to.
 299   
      */
 300  1
     public void setOutput(File out) {
 301  1
         redirector.setOutput(out);
 302   
     }
 303   
 
 304   
     /**
 305   
      * Set the input to use for the task
 306   
      */
 307  0
     public void setInput(File input) {
 308  0
         redirector.setInput(input);
 309   
     }
 310   
 
 311   
     /**
 312   
      * Set the string to use as input
 313   
      *
 314   
      * @param inputString the string which is used as the input source
 315   
      */
 316  0
     public void setInputString(String inputString) {
 317  0
         redirector.setInputString(inputString);
 318   
     }
 319   
     
 320   
     /**
 321   
      * Controls whether error output of exec is logged. This is only useful
 322   
      * when output is being redirected and error output is desired in the
 323   
      * Ant log
 324   
      */
 325  0
     public void setLogError(boolean logError) {
 326  0
         redirector.setLogError(logError);
 327   
     }
 328   
     
 329   
     /**
 330   
      * File the error stream of the process is redirected to.
 331   
      *
 332   
      * @since ant 1.6
 333   
      */
 334  0
     public void setError(File error) {
 335  0
         redirector.setError(error);
 336   
     }
 337   
 
 338   
     /**
 339   
      * Property name whose value should be set to the output of
 340   
      * the process.
 341   
      */
 342  0
     public void setOutputproperty(String outputProp) {
 343  0
         redirector.setOutputProperty(outputProp);
 344   
     }
 345   
 
 346   
     /**
 347   
      * Property name whose value should be set to the error of
 348   
      * the process.
 349   
      *
 350   
      * @since ant 1.6
 351   
      */
 352  0
     public void setErrorProperty(String errorProperty) {
 353  0
         redirector.setErrorProperty(errorProperty);
 354   
     }
 355   
 
 356   
     /**
 357   
      * Corresponds to -mx or -Xmx depending on VM version.
 358   
      */
 359  0
     public void setMaxmemory(String max){
 360  0
         cmdl.setMaxmemory(max);
 361   
     }
 362   
 
 363   
     /**
 364   
      * Sets the JVM version.
 365   
      * @param value JVM version
 366   
      */
 367  0
     public void setJVMVersion(String value) {
 368  0
         cmdl.setVmversion(value);
 369   
     }
 370   
     
 371   
     /**
 372   
      * Adds an environment variable.
 373   
      *
 374   
      * <p>Will be ignored if we are not forking a new VM.
 375   
      *
 376   
      * @since Ant 1.5
 377   
      */
 378  0
     public void addEnv(Environment.Variable var) {
 379  0
         env.addVariable(var);
 380   
     }
 381   
 
 382   
     /**
 383   
      * If true, use a completely new environment.
 384   
      *
 385   
      * <p>Will be ignored if we are not forking a new VM.
 386   
      *
 387   
      * @since Ant 1.5
 388   
      */
 389  0
     public void setNewenvironment(boolean newenv) {
 390  0
         newEnvironment = newenv;
 391   
     }
 392   
 
 393   
     /**
 394   
      * If true, append output to existing file.
 395   
      *
 396   
      * @since Ant 1.5
 397   
      */
 398  0
     public void setAppend(boolean append) {
 399  0
         this.append = append;
 400   
     }
 401   
 
 402   
     /**
 403   
      * Timeout in milliseconds after which the process will be killed.
 404   
      *
 405   
      * @since Ant 1.5
 406   
      */
 407  0
     public void setTimeout(Long value) {
 408  0
         timeout = value;
 409   
     }
 410   
 
 411   
     /**
 412   
      * Pass output sent to System.out to specified output file.
 413   
      *
 414   
      * @since Ant 1.5
 415   
      */
 416  54
     protected void handleOutput(String line) {
 417  54
         if (redirector.getOutputStream() != null) {
 418  54
             redirector.handleOutput(line);
 419   
         } else {
 420  0
             super.handleOutput(line);
 421   
         }
 422   
     }
 423   
     
 424  0
     public int handleInput(byte[] buffer, int offset, int length) 
 425   
         throws IOException {
 426  0
         if (redirector.getInputStream() != null) {
 427  0
             return redirector.handleInput(buffer, offset, length);
 428   
         } else {
 429  0
             return super.handleInput(buffer, offset, length);
 430   
         }
 431   
     }
 432   
 
 433   
     /**
 434   
      * Pass output sent to System.out to specified output file.
 435   
      *
 436   
      * @since Ant 1.5.2
 437   
      */
 438  0
     protected void handleFlush(String line) {
 439  0
         if (redirector.getOutputStream() != null) {
 440  0
             redirector.handleFlush(line);
 441   
         } else {
 442  0
             super.handleFlush(line);
 443   
         }
 444   
     }
 445   
     
 446   
     /**
 447   
      * Pass output sent to System.err to specified output file.
 448   
      *
 449   
      * @since Ant 1.5
 450   
      */
 451  0
     protected void handleErrorOutput(String line) {
 452  0
         if (redirector.getErrorStream() != null) {
 453  0
             redirector.handleErrorOutput(line);
 454   
         } else {
 455  0
             super.handleErrorOutput(line);
 456   
         }
 457   
     }
 458   
     
 459   
     /**
 460   
      * Pass output sent to System.err to specified output file.
 461   
      *
 462   
      * @since Ant 1.5.2
 463   
      */
 464  0
     protected void handleErrorFlush(String line) {
 465  0
         if (redirector.getErrorStream() != null) {
 466  0
             redirector.handleErrorFlush(line);
 467   
         } else {
 468  0
             super.handleErrorOutput(line);
 469   
         }
 470   
     }
 471   
     
 472   
     /**
 473   
      * Executes the given classname with the given arguments as it
 474   
      * was a command line application.
 475   
      */
 476  5
     private void run(CommandlineJava command) throws BuildException {
 477  5
         try {
 478  5
             ExecuteJava exe = new ExecuteJava();
 479  5
             exe.setJavaCommand(command.getJavaCommand());
 480  5
             exe.setClasspath(command.getClasspath());
 481  5
             exe.setSystemProperties(command.getSystemProperties());
 482  5
             exe.setTimeout(timeout);
 483  5
             redirector.createStreams();
 484  5
             exe.execute(getProject());
 485  3
             redirector.complete();
 486   
         } catch (IOException e) {
 487  0
             throw new BuildException(e);
 488   
         }
 489   
     }
 490   
 
 491   
     /**
 492   
      * Executes the given classname with the given arguments in a separate VM.
 493   
      */
 494  10
     private int run(String[] command) throws BuildException {
 495   
             
 496  10
             Execute exe 
 497   
                 = new Execute(redirector.createHandler(), createWatchdog());
 498  10
             exe.setAntRun(getProject());
 499   
             
 500  10
             if (dir == null) {
 501  4
                 dir = getProject().getBaseDir();
 502  6
             } else if (!dir.exists() || !dir.isDirectory()) {
 503  0
                 throw new BuildException(dir.getAbsolutePath()
 504   
                                          + " is not a valid directory",
 505   
                                          getLocation());
 506   
             }
 507   
             
 508  10
             exe.setWorkingDirectory(dir);
 509   
             
 510  10
             String[] environment = env.getVariables();
 511  10
             if (environment != null) {
 512  0
                 for (int i = 0; i < environment.length; i++) {
 513  0
                     log("Setting environment variable: " + environment[i],
 514   
                         Project.MSG_VERBOSE);
 515   
                 }
 516   
             }
 517  10
             exe.setNewenvironment(newEnvironment);
 518  10
             exe.setEnvironment(environment);
 519   
 
 520  10
             exe.setCommandline(command);
 521  10
             try {
 522  10
                 int rc = exe.execute();
 523  10
                 if (exe.killedProcess()) {
 524  0
                     log("Timeout: killed the sub-process", Project.MSG_WARN); 
 525   
                 }
 526  10
                 redirector.complete();
 527  10
                 return rc;
 528   
             } catch (IOException e) {
 529  0
                 throw new BuildException(e, getLocation());
 530   
             }
 531   
     }
 532   
 
 533   
     /**
 534   
      * Executes the given classname with the given arguments as it
 535   
      * was a command line application.
 536   
      */
 537  0
     protected void run(String classname, Vector args) throws BuildException {
 538  0
         CommandlineJava cmdj = new CommandlineJava();
 539  0
         cmdj.setClassname(classname);
 540  0
         for (int i = 0; i < args.size(); i++) {
 541  0
             cmdj.createArgument().setValue((String) args.elementAt(i));
 542   
         }
 543  0
         run(cmdj);
 544   
     }
 545   
 
 546   
     /**
 547   
      * Clear out the arguments to this java task.
 548   
      */
 549  0
     public void clearArgs() {
 550  0
         cmdl.clearJavaArgs();
 551   
     }
 552   
 
 553   
     /**
 554   
      * Create the Watchdog to kill a runaway process.
 555   
      *
 556   
      * @since Ant 1.5
 557   
      */
 558  10
     protected ExecuteWatchdog createWatchdog() throws BuildException {
 559  10
         if (timeout == null) {
 560  10
             return null;
 561   
         }
 562  0
         return new ExecuteWatchdog(timeout.longValue());
 563   
     }
 564   
 
 565   
 }
 566