FileDocCategorySizeDatePackage
ExecuteJava.javaAPI DocApache Ant 1.7011860Wed Dec 13 06:16:18 GMT 2006org.apache.tools.ant.taskdefs

ExecuteJava

public class ExecuteJava extends Object implements org.apache.tools.ant.util.TimeoutObserver, Runnable
Execute a Java class.
since
Ant 1.2

Fields Summary
private org.apache.tools.ant.types.Commandline
javaCommand
private org.apache.tools.ant.types.Path
classpath
private CommandlineJava.SysProperties
sysProperties
private org.apache.tools.ant.types.Permissions
perm
private Method
main
private Long
timeout
private volatile Throwable
caught
private volatile boolean
timedOut
private Thread
thread
Constructors Summary
Methods Summary
public voidexecute(org.apache.tools.ant.Project project)
Execute the Java class against the specified Ant Project.

param
project the Project to use.
throws
BuildException on error.

        final String classname = javaCommand.getExecutable();

        AntClassLoader loader = null;
        try {
            if (sysProperties != null) {
                sysProperties.setSystem();
            }
            Class target = null;
            try {
                if (classpath == null) {
                    target = Class.forName(classname);
                } else {
                    loader = project.createClassLoader(classpath);
                    loader.setParent(project.getCoreLoader());
                    loader.setParentFirst(false);
                    loader.addJavaLibraries();
                    loader.setIsolated(true);
                    loader.setThreadContextLoader();
                    loader.forceLoadClass(classname);
                    target = Class.forName(classname, true, loader);
                }
            } catch (ClassNotFoundException e) {
                throw new BuildException("Could not find " + classname + "."
                                         + " Make sure you have it in your"
                                         + " classpath");
            }
            main = target.getMethod("main", new Class[] {String[].class});
            if (main == null) {
                throw new BuildException("Could not find main() method in "
                                         + classname);
            }
            if ((main.getModifiers() & Modifier.STATIC) == 0) {
                throw new BuildException("main() method in " + classname
                    + " is not declared static");
            }
            if (timeout == null) {
                run();
            } else {
                thread = new Thread(this, "ExecuteJava");
                Task currentThreadTask
                    = project.getThreadTask(Thread.currentThread());
                // XXX is the following really necessary? it is in the same thread group...
                project.registerThreadTask(thread, currentThreadTask);
                // if we run into a timeout, the run-away thread shall not
                // make the VM run forever - if no timeout occurs, Ant's
                // main thread will still be there to let the new thread
                // finish
                thread.setDaemon(true);
                Watchdog w = new Watchdog(timeout.longValue());
                w.addTimeoutObserver(this);
                synchronized (this) {
                    thread.start();
                    w.start();
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        // ignore
                    }
                    if (timedOut) {
                        project.log("Timeout: sub-process interrupted",
                                    Project.MSG_WARN);
                    } else {
                        thread = null;
                        w.stop();
                    }
                }
            }
            if (caught != null) {
                throw caught;
            }
        } catch (BuildException e) {
            throw e;
        } catch (SecurityException e) {
            throw e;
        } catch (ThreadDeath e) {
            // XXX could perhaps also call thread.stop(); not sure if anyone cares
            throw e;
        } catch (Throwable e) {
            throw new BuildException(e);
        } finally {
            if (loader != null) {
                loader.resetThreadContextLoader();
                loader.cleanup();
                loader = null;
            }
            if (sysProperties != null) {
                sysProperties.restoreSystem();
            }
        }
    
public intfork(org.apache.tools.ant.ProjectComponent pc)
Run the Java command in a separate VM, this does not give you the full flexibility of the Java task, but may be enough for simple needs.

param
pc the ProjectComponent to use for logging, etc.
return
the exit status of the subprocess.
throws
BuildException on error.
since
Ant 1.6.3

        CommandlineJava cmdl = new CommandlineJava();
        cmdl.setClassname(javaCommand.getExecutable());
        String[] args = javaCommand.getArguments();
        for (int i = 0; i < args.length; i++) {
            cmdl.createArgument().setValue(args[i]);
        }
        if (classpath != null) {
            cmdl.createClasspath(pc.getProject()).append(classpath);
        }
        if (sysProperties != null) {
            cmdl.addSysproperties(sysProperties);
        }
        Redirector redirector = new Redirector(pc);
        Execute exe
            = new Execute(redirector.createHandler(),
                          timeout == null
                          ? null
                          : new ExecuteWatchdog(timeout.longValue()));
        exe.setAntRun(pc.getProject());
        if (Os.isFamily("openvms")) {
            setupCommandLineForVMS(exe, cmdl.getCommandline());
        } else {
            exe.setCommandline(cmdl.getCommandline());
        }
        try {
            int rc = exe.execute();
            redirector.complete();
            return rc;
        } catch (IOException e) {
            throw new BuildException(e);
        } finally {
            timedOut = exe.killedProcess();
        }
    
public synchronized booleankilledProcess()
Get whether the process was killed.

return
true if the process was killed, false otherwise.
since
1.19, Ant 1.5

        return timedOut;
    
public voidrun()
Run this ExecuteJava in a Thread.

since
Ant 1.5

        final Object[] argument = {javaCommand.getArguments()};
        try {
            if (perm != null) {
                perm.setSecurityManager();
            }
            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 {
            if (perm != null) {
                perm.restoreSecurityManager();
            }
            synchronized (this) {
                notifyAll();
            }
        }
    
public voidsetClasspath(org.apache.tools.ant.types.Path p)
Set the classpath to be used when running the Java class.

param
p an Ant Path object containing the classpath.

        classpath = p;
    
public voidsetJavaCommand(org.apache.tools.ant.types.Commandline javaCommand)
Set the Java "command" for this ExecuteJava.

param
javaCommand the classname and arguments in a Commandline.


                         
        
        this.javaCommand = javaCommand;
    
public voidsetOutput(java.io.PrintStream out)
Set the stream to which all output (System.out as well as System.err) will be written.

param
out the PrintStream where output should be sent.
deprecated
since 1.4.x. manage output at the task level.

    
public voidsetPermissions(org.apache.tools.ant.types.Permissions permissions)
Set the permissions for the application run.

param
permissions the Permissions to use.
since
Ant 1.6

        perm = permissions;
    
public voidsetSystemProperties(CommandlineJava.SysProperties s)
Set the system properties to use when running the Java class.

param
s CommandlineJava system properties.

        sysProperties = s;
    
public voidsetTimeout(java.lang.Long timeout)
Set the timeout for this ExecuteJava.

param
timeout timeout as Long.
since
Ant 1.5

        this.timeout = timeout;
    
public static voidsetupCommandLineForVMS(Execute exe, java.lang.String[] command)
On VMS platform, we need to create a special java options file containing the arguments and classpath for the java command. The special file is supported by the "-V" switch on the VMS JVM.

param
exe the Execute instance to alter.
param
command the command-line.

        //Use the VM launcher instead of shell launcher on VMS
        exe.setVMLauncher(true);
        File vmsJavaOptionFile = null;
        try {
            String [] args = new String[command.length - 1];
            System.arraycopy(command, 1, args, 0, command.length - 1);
            vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args);
            //we mark the file to be deleted on exit.
            //the alternative would be to cache the filename and delete
            //after execution finished, which is much better for long-lived runtimes
            //though spawning complicates things...
            vmsJavaOptionFile.deleteOnExit();
            String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()};
            exe.setCommandline(vmsCmd);
        } catch (IOException e) {
            throw new BuildException("Failed to create a temporary file for \"-V\" switch");
        }
    
public synchronized voidtimeoutOccured(org.apache.tools.ant.util.Watchdog w)
Mark timeout as having occurred.

param
w the responsible Watchdog.
since
Ant 1.5

        if (thread != null) {
            timedOut = true;
            thread.interrupt();
        }
        notifyAll();