git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1350460 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -10,6 +10,10 @@ Changes that could break older environments: | |||
| EOL ASIS will not insert a newline even if fixlast is set to true. | |||
| Bugzilla report 53036 | |||
| * The CommandLauncher hierarchy that used to be a set of inner | |||
| classes of Execute has been extracted to the | |||
| org.apache.tools.ant.taskdefs.launcher package. | |||
| Fixed bugs: | |||
| ----------- | |||
| @@ -36,9 +40,14 @@ Fixed bugs: | |||
| Other changes: | |||
| -------------- | |||
| * merged the ZIP package from Commons Compress, it can now read | |||
| archives using Zip64 extensions (files and archives bigger that 4GB | |||
| and with more that 64k entries). | |||
| * merged the ZIP package from Commons Compress, it can now read | |||
| archives using Zip64 extensions (files and archives bigger that 4GB | |||
| and with more that 64k entries). | |||
| * a new task <commandlaucher> can be used to configure the | |||
| CommandLauncher used by Ant when forking external programs or new | |||
| Java VMs. | |||
| Bugzilla Report 52706. | |||
| Changes from Ant 1.8.3 TO Ant 1.8.4 | |||
| =================================== | |||
| @@ -0,0 +1,33 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.taskdefs.launcher.CommandLauncher; | |||
| public class CommandLauncherTask extends Task { | |||
| private boolean vmLauncher; | |||
| private CommandLauncher commandLauncher; | |||
| public synchronized void addConfigured(CommandLauncher commandLauncher) { | |||
| if (this.commandLauncher != null) { | |||
| throw new BuildException("Only one CommandLauncher can be installed"); | |||
| } | |||
| this.commandLauncher = commandLauncher; | |||
| } | |||
| @Override | |||
| public void execute() { | |||
| if (commandLauncher != null) { | |||
| if (vmLauncher) { | |||
| CommandLauncher.setVMLauncher(getProject(), commandLauncher); | |||
| } else { | |||
| CommandLauncher.setShellLauncher(getProject(), commandLauncher); | |||
| } | |||
| } | |||
| } | |||
| public void setVmLauncher(boolean vmLauncher) { | |||
| this.vmLauncher = vmLauncher; | |||
| } | |||
| } | |||
| @@ -30,6 +30,7 @@ bzip2=org.apache.tools.ant.taskdefs.BZip2 | |||
| checksum=org.apache.tools.ant.taskdefs.Checksum | |||
| chmod=org.apache.tools.ant.taskdefs.Chmod | |||
| classloader=org.apache.tools.ant.taskdefs.Classloader | |||
| commandlaucher=org.apache.tools.ant.taskdefs.CommandLauncherTask | |||
| componentdef=org.apache.tools.ant.taskdefs.Componentdef | |||
| concat=org.apache.tools.ant.taskdefs.Concat | |||
| condition=org.apache.tools.ant.taskdefs.ConditionTask | |||
| @@ -0,0 +1,184 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * A command launcher for a particular JVM/OS platform. This class is | |||
| * a general purpose command launcher which can only launch commands | |||
| * in the current working directory. | |||
| */ | |||
| public class CommandLauncher { | |||
| private static final String ANT_SHELL_LAUNCHER_REF_ID = "ant.shellLauncher"; | |||
| private static final String ANT_VM_LAUNCHER_REF_ID = "ant.vmLauncher"; | |||
| protected static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); | |||
| private static CommandLauncher vmLauncher = null; | |||
| private static CommandLauncher shellLauncher = null; | |||
| static { | |||
| // Try using a JDK 1.3 launcher | |||
| try { | |||
| if(!Os.isFamily("os/2")) { | |||
| vmLauncher = new Java13CommandLauncher(); | |||
| } | |||
| } catch(NoSuchMethodException exc) { | |||
| // Ignore and keep trying | |||
| } | |||
| if (Os.isFamily("mac") && !Os.isFamily("unix")) { | |||
| // Mac | |||
| shellLauncher = new MacCommandLauncher(new CommandLauncher()); | |||
| } else if (Os.isFamily("os/2")) { | |||
| // OS/2 | |||
| shellLauncher = new OS2CommandLauncher(new CommandLauncher()); | |||
| } else if (Os.isFamily("windows")) { | |||
| CommandLauncher baseLauncher = new CommandLauncher(); | |||
| if (!Os.isFamily("win9x")) { | |||
| // Windows XP/2000/NT | |||
| shellLauncher = new WinNTCommandLauncher(baseLauncher); | |||
| } else { | |||
| // Windows 98/95 - need to use an auxiliary script | |||
| shellLauncher = new ScriptCommandLauncher("bin/antRun.bat", baseLauncher); | |||
| } | |||
| } else if (Os.isFamily("netware")) { | |||
| CommandLauncher baseLauncher = new CommandLauncher(); | |||
| shellLauncher = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); | |||
| } else if (Os.isFamily("openvms")) { | |||
| // OpenVMS | |||
| try { | |||
| shellLauncher = new VmsCommandLauncher(); | |||
| } catch(NoSuchMethodException exc) { | |||
| // Ignore and keep trying | |||
| } | |||
| } else { | |||
| // Generic | |||
| shellLauncher = new ScriptCommandLauncher("bin/antRun", new CommandLauncher()); | |||
| } | |||
| } | |||
| /** | |||
| * Launches the given command in a new process. | |||
| * | |||
| * @param project | |||
| * The project that the command is part of. | |||
| * @param cmd | |||
| * The command to execute. | |||
| * @param env | |||
| * The environment for the new process. If null, the | |||
| * environment of the current process is used. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * if attempting to run a command in a specific directory. | |||
| */ | |||
| public Process exec(Project project, String[] cmd, String[] env) throws IOException { | |||
| if(project != null) { | |||
| project.log("Execute:CommandLauncher: " + Commandline.describeCommand(cmd), Project.MSG_DEBUG); | |||
| } | |||
| return Runtime.getRuntime().exec(cmd, env); | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * The project that the command is part of. | |||
| * @param cmd | |||
| * The command to execute. | |||
| * @param env | |||
| * The environment for the new process. If null, the | |||
| * environment of the current process is used. | |||
| * @param workingDir | |||
| * The directory to start the command in. If null, the | |||
| * current directory is used. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * if trying to change directory. | |||
| */ | |||
| public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException { | |||
| if(workingDir == null) { | |||
| return exec(project, cmd, env); | |||
| } | |||
| throw new IOException("Cannot execute a process in different " | |||
| + "directory under this JVM"); | |||
| } | |||
| public static CommandLauncher getShellLauncher(Project project) { | |||
| CommandLauncher launcher = null; | |||
| if(project != null) { | |||
| launcher = (CommandLauncher) project | |||
| .getReference(ANT_SHELL_LAUNCHER_REF_ID); | |||
| } | |||
| if (launcher == null) { | |||
| launcher = getSystemLauncher(ANT_SHELL_LAUNCHER_REF_ID); | |||
| } | |||
| if (launcher == null) { | |||
| launcher = shellLauncher; | |||
| } | |||
| return launcher; | |||
| } | |||
| public static CommandLauncher getVMLauncher(Project project) { | |||
| CommandLauncher launcher = null; | |||
| if (project != null) { | |||
| launcher = (CommandLauncher)project.getReference(ANT_VM_LAUNCHER_REF_ID); | |||
| } | |||
| if (launcher == null) { | |||
| launcher = getSystemLauncher(ANT_VM_LAUNCHER_REF_ID); | |||
| } | |||
| if (launcher == null) { | |||
| launcher = vmLauncher; | |||
| } | |||
| return launcher; | |||
| } | |||
| private static CommandLauncher getSystemLauncher(String launcherRefId) { | |||
| CommandLauncher launcher = null; | |||
| String launcherClass = System.getProperty(launcherRefId); | |||
| if (launcherClass != null) { | |||
| try { | |||
| launcher = (CommandLauncher) Class.forName(launcherClass) | |||
| .newInstance(); | |||
| } | |||
| catch(InstantiationException e) { | |||
| System.err.println("Could not instantiate launcher class " | |||
| + launcherClass + ": " + e.getMessage()); | |||
| } | |||
| catch(IllegalAccessException e) { | |||
| System.err.println("Could not instantiate launcher class " | |||
| + launcherClass + ": " + e.getMessage()); | |||
| } | |||
| catch(ClassNotFoundException e) { | |||
| System.err.println("Could not instantiate launcher class " | |||
| + launcherClass + ": " + e.getMessage()); | |||
| } | |||
| } | |||
| return launcher; | |||
| } | |||
| public static void setVMLauncher(Project project, CommandLauncher launcher) { | |||
| if (project != null) { | |||
| project.addReference(ANT_VM_LAUNCHER_REF_ID, launcher); | |||
| } | |||
| } | |||
| public static void setShellLauncher(Project project, CommandLauncher launcher) { | |||
| if (project != null) { | |||
| project.addReference(ANT_SHELL_LAUNCHER_REF_ID, launcher); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,37 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher that proxies another command | |||
| * launcher. Sub-classes override exec(args, env, workdir). | |||
| */ | |||
| public class CommandLauncherProxy extends CommandLauncher { | |||
| private final CommandLauncher myLauncher; | |||
| protected CommandLauncherProxy(CommandLauncher launcher) { | |||
| myLauncher = launcher; | |||
| } | |||
| /** | |||
| * Launches the given command in a new process. Delegates this | |||
| * method to the proxied launcher. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env) | |||
| throws IOException { | |||
| return myLauncher.exec(project, cmd, env); | |||
| } | |||
| } | |||
| @@ -0,0 +1,53 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| /** | |||
| * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in | |||
| * Runtime.exec() command. | |||
| */ | |||
| public class Java13CommandLauncher extends CommandLauncher { | |||
| public Java13CommandLauncher() throws NoSuchMethodException { | |||
| // Used to verify if Java13 is available, is prerequisite in ant 1.8 | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * the working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * probably forwarded from Runtime#exec. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| try { | |||
| if (project != null) { | |||
| project.log("Execute:Java13CommandLauncher: " | |||
| + Commandline.describeCommand(cmd), | |||
| Project.MSG_DEBUG); | |||
| } | |||
| return Runtime.getRuntime().exec(cmd, env, workingDir); | |||
| } catch(IOException ioex) { | |||
| throw ioex; | |||
| } catch(Exception exc) { | |||
| // IllegalAccess, IllegalArgument, ClassCast | |||
| throw new BuildException("Unable to execute command", exc); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,47 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher for Mac that uses a dodgy mechanism to change | |||
| * working directory before launching commands. | |||
| */ | |||
| public class MacCommandLauncher extends CommandLauncherProxy { | |||
| public MacCommandLauncher(CommandLauncher launcher) { | |||
| super(launcher); | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| if (workingDir == null) { | |||
| return exec(project, cmd, env); | |||
| } | |||
| System.getProperties().put("user.dir", workingDir.getAbsolutePath()); | |||
| try { | |||
| return exec(project, cmd, env); | |||
| } | |||
| finally { | |||
| System.getProperties().put("user.dir", System.getProperty("user.dir")); | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,65 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher for OS/2 that uses 'cmd.exe' when launching | |||
| * commands in directories other than the current working directory. | |||
| * | |||
| * <p>Unlike Windows NT and friends, OS/2's cd doesn't support the /d | |||
| * switch to change drives and directories in one go.</p> | |||
| */ | |||
| public class OS2CommandLauncher extends CommandLauncherProxy { | |||
| public OS2CommandLauncher(CommandLauncher launcher) { | |||
| super(launcher); | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| File commandDir = workingDir; | |||
| if (workingDir == null) { | |||
| if (project != null) { | |||
| commandDir = project.getBaseDir(); | |||
| } else { | |||
| return exec(project, cmd, env); | |||
| } | |||
| } | |||
| // Use cmd.exe to change to the specified drive and | |||
| // directory before running the command | |||
| final int preCmdLength = 7; | |||
| final String cmdDir = commandDir.getAbsolutePath(); | |||
| String[] newcmd = new String[cmd.length + preCmdLength]; | |||
| // CheckStyle:MagicNumber OFF - do not bother | |||
| newcmd[0] = "cmd"; | |||
| newcmd[1] = "/c"; | |||
| newcmd[2] = cmdDir.substring(0, 2); | |||
| newcmd[3] = "&&"; | |||
| newcmd[4] = "cd"; | |||
| newcmd[5] = cmdDir.substring(2); | |||
| newcmd[6] = "&&"; | |||
| // CheckStyle:MagicNumber ON | |||
| System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length); | |||
| return exec(project, newcmd, env); | |||
| } | |||
| } | |||
| @@ -0,0 +1,73 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.MagicNames; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher that uses an auxiliary perl script to launch | |||
| * commands in directories other than the current working directory. | |||
| */ | |||
| public class PerlScriptCommandLauncher extends CommandLauncherProxy { | |||
| private final String myScript; | |||
| public PerlScriptCommandLauncher(String script, CommandLauncher launcher) { | |||
| super(launcher); | |||
| myScript = script; | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| if (project == null) { | |||
| if(workingDir == null) { | |||
| return exec(project, cmd, env); | |||
| } | |||
| throw new IOException("Cannot locate antRun script: " | |||
| + "No project provided"); | |||
| } | |||
| // Locate the auxiliary script | |||
| String antHome = project.getProperty(MagicNames.ANT_HOME); | |||
| if (antHome == null) { | |||
| throw new IOException("Cannot locate antRun script: " | |||
| + "Property '" + MagicNames.ANT_HOME | |||
| + "' not found"); | |||
| } | |||
| String antRun = FILE_UTILS.resolveFile(project.getBaseDir(), | |||
| antHome + File.separator | |||
| + myScript).toString(); | |||
| // Build the command | |||
| File commandDir = workingDir; | |||
| if (workingDir == null) { | |||
| commandDir = project.getBaseDir(); | |||
| } | |||
| // CheckStyle:MagicNumber OFF | |||
| String[] newcmd = new String[cmd.length + 3]; | |||
| newcmd[0] = "perl"; | |||
| newcmd[1] = antRun; | |||
| newcmd[2] = commandDir.getAbsolutePath(); | |||
| System.arraycopy(cmd, 0, newcmd, 3, cmd.length); | |||
| // CheckStyle:MagicNumber ON | |||
| return exec(project, newcmd, env); | |||
| } | |||
| } | |||
| @@ -0,0 +1,71 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.MagicNames; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher that uses an auxiliary script to launch commands | |||
| * in directories other than the current working directory. | |||
| */ | |||
| public class ScriptCommandLauncher extends CommandLauncherProxy { | |||
| private final String myScript; | |||
| public ScriptCommandLauncher(String script, CommandLauncher launcher) { | |||
| super(launcher); | |||
| myScript = script; | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| if (project == null) { | |||
| if (workingDir == null) { | |||
| return exec(project, cmd, env); | |||
| } | |||
| throw new IOException("Cannot locate antRun script: " | |||
| + "No project provided"); | |||
| } | |||
| // Locate the auxiliary script | |||
| String antHome = project.getProperty(MagicNames.ANT_HOME); | |||
| if(antHome == null) { | |||
| throw new IOException("Cannot locate antRun script: " | |||
| + "Property '" + MagicNames.ANT_HOME | |||
| + "' not found"); | |||
| } | |||
| String antRun = FILE_UTILS.resolveFile(project.getBaseDir(), | |||
| antHome + File.separator | |||
| + myScript).toString(); | |||
| // Build the command | |||
| File commandDir = workingDir; | |||
| if(workingDir == null) { | |||
| commandDir = project.getBaseDir(); | |||
| } | |||
| String[] newcmd = new String[cmd.length + 2]; | |||
| newcmd[0] = antRun; | |||
| newcmd[1] = commandDir.getAbsolutePath(); | |||
| System.arraycopy(cmd, 0, newcmd, 2, cmd.length); | |||
| return exec(project, newcmd, env); | |||
| } | |||
| } | |||
| @@ -0,0 +1,128 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.BufferedWriter; | |||
| import java.io.File; | |||
| import java.io.FileWriter; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * A command launcher for VMS that writes the command to a temporary | |||
| * DCL script before launching commands. This is due to limitations of | |||
| * both the DCL interpreter and the Java VM implementation. | |||
| */ | |||
| public class VmsCommandLauncher extends Java13CommandLauncher { | |||
| public VmsCommandLauncher() throws NoSuchMethodException { | |||
| super(); | |||
| } | |||
| /** | |||
| * Launches the given command in a new process. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env) | |||
| throws IOException { | |||
| File cmdFile = createCommandFile(cmd, env); | |||
| Process p = super.exec(project, new String[] {cmdFile.getPath()}, env); | |||
| deleteAfter(cmdFile, p); | |||
| return p; | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. Note that under Java 1.4.0 and 1.4.1 on VMS | |||
| * this method only works if <code>workingDir</code> is null or | |||
| * the logical JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| File cmdFile = createCommandFile(cmd, env); | |||
| Process p = super.exec(project, new String[] { | |||
| cmdFile.getPath() | |||
| }, env, workingDir); | |||
| deleteAfter(cmdFile, p); | |||
| return p; | |||
| } | |||
| /* | |||
| * Writes the command into a temporary DCL script and returns the | |||
| * corresponding File object. The script will be deleted on exit. | |||
| * @param cmd the command line to execute as an array of strings. | |||
| * @param env the environment to set as an array of strings. | |||
| * @return the command File. | |||
| * @throws IOException if errors are encountered creating the file. | |||
| */ | |||
| private File createCommandFile(String[] cmd, String[] env) | |||
| throws IOException { | |||
| File script = FILE_UTILS.createTempFile("ANT", ".COM", null, true, true); | |||
| BufferedWriter out = null; | |||
| try { | |||
| out = new BufferedWriter(new FileWriter(script)); | |||
| // add the environment as logicals to the DCL script | |||
| if (env != null) { | |||
| int eqIndex; | |||
| for (int i = 0; i < env.length; i++) { | |||
| eqIndex = env[i].indexOf('='); | |||
| if (eqIndex != -1) { | |||
| out.write("$ DEFINE/NOLOG "); | |||
| out.write(env[i].substring(0, eqIndex)); | |||
| out.write(" \""); | |||
| out.write(env[i].substring(eqIndex + 1)); | |||
| out.write('\"'); | |||
| out.newLine(); | |||
| } | |||
| } | |||
| } | |||
| out.write("$ " + cmd[0]); | |||
| for (int i = 1; i < cmd.length; i++) { | |||
| out.write(" -"); | |||
| out.newLine(); | |||
| out.write(cmd[i]); | |||
| } | |||
| } finally { | |||
| FileUtils.close(out); | |||
| } | |||
| return script; | |||
| } | |||
| private void deleteAfter(final File f, final Process p) { | |||
| new Thread() { | |||
| @Override | |||
| public void run() { | |||
| try { | |||
| p.waitFor(); | |||
| } catch(InterruptedException e) { | |||
| // ignore | |||
| } | |||
| FileUtils.delete(f); | |||
| } | |||
| }.start(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,61 @@ | |||
| package org.apache.tools.ant.taskdefs.launcher; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import org.apache.tools.ant.Project; | |||
| /** | |||
| * A command launcher for Windows XP/2000/NT that uses 'cmd.exe' when | |||
| * launching commands in directories other than the current working | |||
| * directory. | |||
| */ | |||
| public class WinNTCommandLauncher extends CommandLauncherProxy { | |||
| public WinNTCommandLauncher(CommandLauncher launcher) { | |||
| super(launcher); | |||
| } | |||
| /** | |||
| * Launches the given command in a new process, in the given | |||
| * working directory. | |||
| * | |||
| * @param project | |||
| * the Ant project. | |||
| * @param cmd | |||
| * the command line to execute as an array of strings. | |||
| * @param env | |||
| * the environment to set as an array of strings. | |||
| * @param workingDir | |||
| * working directory where the command should run. | |||
| * @return the created Process. | |||
| * @throws IOException | |||
| * forwarded from the exec method of the command launcher. | |||
| */ | |||
| @Override | |||
| public Process exec(Project project, String[] cmd, String[] env, | |||
| File workingDir) throws IOException { | |||
| File commandDir = workingDir; | |||
| if (workingDir == null) { | |||
| if (project != null) { | |||
| commandDir = project.getBaseDir(); | |||
| } else { | |||
| return exec(project, cmd, env); | |||
| } | |||
| } | |||
| // Use cmd.exe to change to the specified directory before running | |||
| // the command | |||
| final int preCmdLength = 6; | |||
| String[] newcmd = new String[cmd.length + preCmdLength]; | |||
| // CheckStyle:MagicNumber OFF - do not bother | |||
| newcmd[0] = "cmd"; | |||
| newcmd[1] = "/c"; | |||
| newcmd[2] = "cd"; | |||
| newcmd[3] = "/d"; | |||
| newcmd[4] = commandDir.getAbsolutePath(); | |||
| newcmd[5] = "&&"; | |||
| // CheckStyle:MagicNumber ON | |||
| System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length); | |||
| return exec(project, newcmd, env); | |||
| } | |||
| } | |||