FileDocCategorySizeDatePackage
ExecTask.javaAPI DocApache Ant 1.7022603Wed Dec 13 06:16:24 GMT 2006org.apache.tools.ant.taskdefs

ExecTask

public class ExecTask extends org.apache.tools.ant.Task
Executes a given command if the os platform is appropriate.
since
Ant 1.2
ant.task
category="control"

Fields Summary
private static final org.apache.tools.ant.util.FileUtils
FILE_UTILS
private String
os
private String
osFamily
private File
dir
protected boolean
failOnError
protected boolean
newEnvironment
private Long
timeout
private org.apache.tools.ant.types.Environment
env
protected org.apache.tools.ant.types.Commandline
cmdl
private String
resultProperty
private boolean
failIfExecFails
private String
executable
private boolean
resolveExecutable
private boolean
searchPath
private boolean
spawn
private boolean
incompatibleWithSpawn
private String
inputString
private File
input
private File
output
private File
error
protected Redirector
redirector
protected org.apache.tools.ant.types.RedirectorElement
redirectorElement
private boolean
vmLauncher
Controls whether the VM (1.3 and above) is used to execute the command
Constructors Summary
public ExecTask()
Create an instance. Needs to be configured by binding to a project.



                     
      
    
public ExecTask(org.apache.tools.ant.Task owner)
create an instance that is helping another task. Project, OwningTarget, TaskName and description are all pulled out

param
owner task that we belong to

        bindToOwner(owner);
    
Methods Summary
public voidaddConfiguredRedirector(org.apache.tools.ant.types.RedirectorElement redirectorElement)
Add a RedirectorElement to this task.

param
redirectorElement RedirectorElement.
since
Ant 1.6.2

        if (this.redirectorElement != null) {
            throw new BuildException("cannot have > 1 nested <redirector>s");
        }
        this.redirectorElement = redirectorElement;
        incompatibleWithSpawn = true;
    
public voidaddEnv(Environment.Variable var)
Add an environment variable to the launched process.

param
var new environment variable.

        env.addVariable(var);
    
protected voidcheckConfiguration()
Has the user set all necessary attributes?

throws
BuildException if there are missing required parameters.

        if (cmdl.getExecutable() == null) {
            throw new BuildException("no executable specified", getLocation());
        }
        if (dir != null && !dir.exists()) {
            throw new BuildException("The directory " + dir + " does not exist");
        }
        if (dir != null && !dir.isDirectory()) {
            throw new BuildException(dir + " is not a directory");
        }
        if (spawn && incompatibleWithSpawn) {
            getProject().log("spawn does not allow attributes related to input, "
            + "output, error, result", Project.MSG_ERR);
            getProject().log("spawn also does not allow timeout", Project.MSG_ERR);
            getProject().log("finally, spawn is not compatible "
                + "with a nested I/O <redirector>", Project.MSG_ERR);
            throw new BuildException("You have used an attribute "
                + "or nested element which is not compatible with spawn");
        }
        setupRedirector();
    
public Commandline.ArgumentcreateArg()
Adds a command-line argument.

return
new command line argument created.

        return cmdl.createArgument();
    
protected ExecuteStreamHandlercreateHandler()
Create the StreamHandler to use with our Execute instance.

return
instance of ExecuteStreamHandler.
throws
BuildException under unknown circumstances.

        return redirector.createHandler();
    
protected ExecuteWatchdogcreateWatchdog()
Create the Watchdog to kill a runaway process.

return
instance of ExecuteWatchdog.
throws
BuildException under unknown circumstances.

        return (timeout == null)
            ? null : new ExecuteWatchdog(timeout.longValue());
    
public voidexecute()
Do the work.

throws
BuildException in a number of circumstances:
  • if failIfExecFails is set to true and the process cannot be started
  • the java13command launcher can send build exceptions
  • this list is not exhaustive or limitative

        // Quick fail if this is not a valid OS for the command
        if (!isValidOs()) {
            return;
        }
        File savedDir = dir; // possibly altered in prepareExec
        cmdl.setExecutable(resolveExecutable(executable, searchPath));
        checkConfiguration();
        try {
            runExec(prepareExec());
        } finally {
            dir = savedDir;
        }
    
public booleangetResolveExecutable()
Indicates whether to attempt to resolve the executable to a file.

return
the resolveExecutable flag
since
Ant 1.6

        return resolveExecutable;
    
private booleanisPath(java.lang.String line)

        return line.startsWith("PATH=") || line.startsWith("Path=");
    
protected booleanisValidOs()
Is this the OS the user wanted?

return
boolean.
  • true if the os and osfamily attributes are null.
  • true if osfamily is set, and the os family and must match that of the current OS, according to the logic of {@link Os#isOs(String, String, String, String)}, and the result of the os attribute must also evaluate true.
  • true if os is set, and the system.property os.name is found in the os attribute,
  • false otherwise.

        //hand osfamily off to Os class, if set
        if (osFamily != null && !Os.isOs(osFamily, null, null, null)) {
            return false;
        }
        //the Exec OS check is different from Os.isOs(), which
        //probes for a specific OS. Instead it searches the os field
        //for the current os.name
        String myos = System.getProperty("os.name");
        log("Current OS is " + myos, Project.MSG_VERBOSE);
        if ((os != null) && (os.indexOf(myos) < 0)) {
            // this command will be executed only on the specified OS
            log("This OS, " + myos
                    + " was not found in the specified list of valid OSes: " + os,
                    Project.MSG_VERBOSE);
            return false;
        }
        return true;
    
protected voidlogFlush()
Flush the output stream - if there is one.

    
protected voidmaybeSetResultPropertyValue(int result)
Helper method to set result property to the passed in value if appropriate.

param
result value desired for the result property value.

        if (resultProperty != null) {
            String res = Integer.toString(result);
            getProject().setNewProperty(resultProperty, res);
        }
    
protected ExecuteprepareExec()
Create an Execute instance with the correct working directory set.

return
an instance of the Execute class.
throws
BuildException under unknown circumstances.

        // default directory to the project's base directory
        if (dir == null) {
            dir = getProject().getBaseDir();
        }
        if (redirectorElement != null) {
            redirectorElement.configure(redirector);
        }
        Execute exe = new Execute(createHandler(), createWatchdog());
        exe.setAntRun(getProject());
        exe.setWorkingDirectory(dir);
        exe.setVMLauncher(vmLauncher);
        exe.setSpawn(spawn);
        String[] environment = env.getVariables();
        if (environment != null) {
            for (int i = 0; i < environment.length; i++) {
                log("Setting environment variable: " + environment[i],
                    Project.MSG_VERBOSE);
            }
        }
        exe.setNewenvironment(newEnvironment);
        exe.setEnvironment(environment);
        return exe;
    
protected java.lang.StringresolveExecutable(java.lang.String exec, boolean mustSearchPath)
The method attempts to figure out where the executable is so that we can feed the full path. We first try basedir, then the exec dir, and then fallback to the straight executable name (i.e. on the path).

param
exec the name of the executable.
param
mustSearchPath if true, the executable will be looked up in the PATH environment and the absolute path is returned.
return
the executable as a full path if it can be determined.
since
Ant 1.6

        if (!resolveExecutable) {
            return exec;
        }
        // try to find the executable
        File executableFile = getProject().resolveFile(exec);
        if (executableFile.exists()) {
            return executableFile.getAbsolutePath();
        }
        // now try to resolve against the dir if given
        if (dir != null) {
            executableFile = FILE_UTILS.resolveFile(dir, exec);
            if (executableFile.exists()) {
                return executableFile.getAbsolutePath();
            }
        }
        // couldn't find it - must be on path
        if (mustSearchPath) {
            Path p = null;
            String[] environment = env.getVariables();
            if (environment != null) {
                for (int i = 0; i < environment.length; i++) {
                    if (isPath(environment[i])) {
                        p = new Path(getProject(), environment[i].substring(5));
                        break;
                    }
                }
            }
            if (p == null) {
                Vector envVars = Execute.getProcEnvironment();
                Enumeration e = envVars.elements();
                while (e.hasMoreElements()) {
                    String line = (String) e.nextElement();
                    if (isPath(line)) {
                        p = new Path(getProject(), line.substring(5));
                        break;
                    }
                }
            }
            if (p != null) {
                String[] dirs = p.list();
                for (int i = 0; i < dirs.length; i++) {
                    executableFile
                        = FILE_UTILS.resolveFile(new File(dirs[i]), exec);
                    if (executableFile.exists()) {
                        return executableFile.getAbsolutePath();
                    }
                }
            }
        }
        // mustSearchPath is false, or no PATH or not found - keep our
        // fingers crossed.
        return exec;
    
protected voidrunExec(Execute exe)
Run the command using the given Execute instance. This may be overridden by subclasses.

param
exe instance of Execute to run.
throws
BuildException if the new process could not be started only if failIfExecFails is set to true (the default).

        // show the command
        log(cmdl.describeCommand(), Project.MSG_VERBOSE);

        exe.setCommandline(cmdl.getCommandline());
        try {
            runExecute(exe);
        } catch (IOException e) {
            if (failIfExecFails) {
                throw new BuildException("Execute failed: " + e.toString(), e,
                                         getLocation());
            } else {
                log("Execute failed: " + e.toString(), Project.MSG_ERR);
            }
        } finally {
            // close the output file if required
            logFlush();
        }
    
protected final voidrunExecute(Execute exe)
A Utility method for this classes and subclasses to run an Execute instance (an external command).

param
exe instance of the execute class.
throws
IOException in case of problem to attach to the stdin/stdout/stderr streams of the process.

        int returnCode = -1; // assume the worst

        if (!spawn) {
            returnCode = exe.execute();

            //test for and handle a forced process death
            if (exe.killedProcess()) {
                String msg = "Timeout: killed the sub-process";
                if (failOnError) {
                    throw new BuildException(msg);
                } else {
                    log(msg, Project.MSG_WARN);
                }
            }
            maybeSetResultPropertyValue(returnCode);
            redirector.complete();
            if (Execute.isFailure(returnCode)) {
                if (failOnError) {
                    throw new BuildException(getTaskType() + " returned: "
                        + returnCode, getLocation());
                } else {
                    log("Result: " + returnCode, Project.MSG_ERR);
                }
            }
        } else {
            exe.spawn();
        }
    
public voidsetAppend(boolean append)
Set whether output should be appended to or overwrite an existing file. Defaults to false.

param
append if true append is desired.
since
1.30, Ant 1.5

        redirector.setAppend(append);
        incompatibleWithSpawn = true;
    
public voidsetCommand(org.apache.tools.ant.types.Commandline cmdl)
Sets a command line.

param
cmdl command line.
ant.attribute
ignore="true"

        log("The command attribute is deprecated.\n"
            + "Please use the executable attribute and nested arg elements.",
            Project.MSG_WARN);
        this.cmdl = cmdl;
    
public voidsetDir(java.io.File d)
Set the working directory of the process.

param
d the working directory of the process.

        this.dir = d;
    
public voidsetError(java.io.File error)
Set the File to which the error stream of the process should be redirected.

param
error a file to which stderr should be sent.
since
Ant 1.6

        this.error = error;
        incompatibleWithSpawn = true;
    
public voidsetErrorProperty(java.lang.String errorProperty)
Sets the name of the property whose value should be set to the error of the process.

param
errorProperty name of property.
since
Ant 1.6

        redirector.setErrorProperty(errorProperty);
        incompatibleWithSpawn = true;
    
public voidsetExecutable(java.lang.String value)
Set the name of the executable program.

param
value the name of the executable program.

        this.executable = value;
        cmdl.setExecutable(value);
    
public voidsetFailIfExecutionFails(boolean flag)
Set whether to stop the build if program cannot be started. Defaults to true.

param
flag stop the build if program cannot be started.
since
Ant 1.5

        failIfExecFails = flag;
        incompatibleWithSpawn = true;
    
public voidsetFailonerror(boolean fail)
Fail if the command exits with a non-zero return code.

param
fail if true fail the command on non-zero return code.

        failOnError = fail;
        incompatibleWithSpawn |= fail;
    
public voidsetInput(java.io.File input)
Set the input file to use for the task.

param
input name of a file from which to get input.

        if (inputString != null) {
            throw new BuildException("The \"input\" and \"inputstring\" "
                + "attributes cannot both be specified");
        }
        this.input = input;
        incompatibleWithSpawn = true;
    
public voidsetInputString(java.lang.String inputString)
Set the string to use as input.

param
inputString the string which is used as the input source.

        if (input != null) {
            throw new BuildException("The \"input\" and \"inputstring\" "
                + "attributes cannot both be specified");
        }
        this.inputString = inputString;
        incompatibleWithSpawn = true;
    
public voidsetLogError(boolean logError)
Controls whether error output of exec is logged. This is only useful when output is being redirected and error output is desired in the Ant log.

param
logError set to true to log error output in the normal ant log.

        redirector.setLogError(logError);
        incompatibleWithSpawn |= logError;
    
public voidsetNewenvironment(boolean newenv)
Do not propagate old environment when new environment variables are specified.

param
newenv if true, do not propagate old environment when new environment variables are specified.

        newEnvironment = newenv;
    
public voidsetOs(java.lang.String os)
List of operating systems on which the command may be executed.

param
os list of operating systems on which the command may be executed.

        this.os = os;
    
public voidsetOsFamily(java.lang.String osFamily)
Restrict this execution to a single OS Family

param
osFamily the family to restrict to.

        this.osFamily = osFamily.toLowerCase(Locale.US);
    
public voidsetOutput(java.io.File out)
File the output of the process is redirected to. If error is not redirected, it too will appear in the output.

param
out name of a file to which output should be sent.

        this.output = out;
        incompatibleWithSpawn = true;
    
public voidsetOutputproperty(java.lang.String outputProp)
Sets the property name whose value should be set to the output of the process.

param
outputProp name of property.

        redirector.setOutputProperty(outputProp);
        incompatibleWithSpawn = true;
    
public voidsetResolveExecutable(boolean resolveExecutable)
Set whether to attempt to resolve the executable to a file.

param
resolveExecutable if true, attempt to resolve the path of the executable.

        this.resolveExecutable = resolveExecutable;
    
public voidsetResultProperty(java.lang.String resultProperty)
Sets the name of a property in which the return code of the command should be stored. Only of interest if failonerror=false.

since
Ant 1.5
param
resultProperty name of property.

        this.resultProperty = resultProperty;
        incompatibleWithSpawn = true;
    
public voidsetSearchPath(boolean searchPath)
Set whether to search nested, then system PATH environment variables for the executable.

param
searchPath if true, search PATHs.

        this.searchPath = searchPath;
    
public voidsetSpawn(boolean spawn)
Set whether or not you want the process to be spawned. Default is false.

param
spawn if true you do not want Ant to wait for the end of the process.
since
Ant 1.6

        this.spawn = spawn;
    
public voidsetTimeout(java.lang.Long value)
Set the timeout in milliseconds after which the process will be killed.

param
value timeout in milliseconds.
since
Ant 1.5

        timeout = value;
        incompatibleWithSpawn = true;
    
public voidsetTimeout(java.lang.Integer value)
Set the timeout in milliseconds after which the process will be killed.

param
value timeout in milliseconds.

        setTimeout(
            (Long) ((value == null) ? null : new Long(value.intValue())));
    
public voidsetVMLauncher(boolean vmLauncher)
Set whether to launch new process with VM, otherwise use the OS's shell. Default value is true.

param
vmLauncher true if we want to launch new process with VM, false if we want to use the OS's shell.

        this.vmLauncher = vmLauncher;
    
protected voidsetupRedirector()
Set up properties on the redirector that we needed to store locally.

        redirector.setInput(input);
        redirector.setInputString(inputString);
        redirector.setOutput(output);
        redirector.setError(error);