|
Ant example source code file (ExecuteJava.java)
The ExecuteJava.java source code/* * 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()); // 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(); } } } /** * 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 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"); } } } Other Ant examples (source code examples)Here is a short list of links related to this Ant ExecuteJava.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.