aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java331
1 files changed, 331 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
new file mode 100644
index 00000000..b78b9a6a
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/ExecuteJava.java
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.tools.ant.taskdefs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tools.ant.AntClassLoader;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.condition.Os;
+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.types.Permissions;
+import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.TimeoutObserver;
+import org.apache.tools.ant.util.Watchdog;
+
+/**
+ * Execute a Java class.
+ * @since Ant 1.2
+ */
+public class ExecuteJava implements Runnable, TimeoutObserver {
+
+ private Commandline javaCommand = null;
+ private Path classpath = null;
+ private CommandlineJava.SysProperties sysProperties = null;
+ private Permissions perm = null;
+ private Method main = null;
+ private Long timeout = null;
+ private volatile Throwable caught = null;
+ private volatile boolean timedOut = false;
+ private Thread thread = null;
+
+ /**
+ * Set the Java "command" for this ExecuteJava.
+ * @param javaCommand the classname and arguments in a Commandline.
+ */
+ public void setJavaCommand(Commandline javaCommand) {
+ this.javaCommand = javaCommand;
+ }
+
+ /**
+ * Set the classpath to be used when running the Java class.
+ *
+ * @param p an Ant Path object containing the classpath.
+ */
+ public void setClasspath(Path p) {
+ classpath = p;
+ }
+
+ /**
+ * Set the system properties to use when running the Java class.
+ * @param s CommandlineJava system properties.
+ */
+ public void setSystemProperties(CommandlineJava.SysProperties s) {
+ sysProperties = s;
+ }
+
+ /**
+ * Set the permissions for the application run.
+ * @param permissions the Permissions to use.
+ * @since Ant 1.6
+ */
+ public void setPermissions(Permissions permissions) {
+ perm = permissions;
+ }
+
+ /**
+ * 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 void setOutput(PrintStream out) {
+ }
+
+ /**
+ * Set the timeout for this ExecuteJava.
+ * @param timeout timeout as Long.
+ * @since Ant 1.5
+ */
+ public void setTimeout(Long timeout) {
+ this.timeout = timeout;
+ }
+
+ /**
+ * Execute the Java class against the specified Ant Project.
+ * @param project the Project to use.
+ * @throws BuildException on error.
+ */
+ public void execute(Project project) throws BuildException {
+ 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());
+ // TODO 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) {
+ // TODO 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();
+ }
+ }
+ }
+
+ /**
+ * Run this ExecuteJava in a Thread.
+ * @since Ant 1.5
+ */
+ public void run() {
+ 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();
+ }
+ }
+ }
+
+ /**
+ * Mark timeout as having occurred.
+ * @param w the responsible Watchdog.
+ * @since Ant 1.5
+ */
+ public synchronized void timeoutOccured(Watchdog w) {
+ if (thread != null) {
+ timedOut = true;
+ thread.interrupt();
+ }
+ notifyAll();
+ }
+
+ /**
+ * Get whether the process was killed.
+ * @return <code>true</code> if the process was killed, false otherwise.
+ * @since 1.19, Ant 1.5
+ */
+ public synchronized boolean killedProcess() {
+ return timedOut;
+ }
+
+ /**
+ * 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
+ */
+ public int fork(ProjectComponent pc) throws BuildException {
+ 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();
+ }
+ }
+
+ /**
+ * 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.
+ */
+ public static void setupCommandLineForVMS(Execute exe, String[] command) {
+ //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");
+ }
+ }
+
+}