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. | EOL ASIS will not insert a newline even if fixlast is set to true. | ||||
| Bugzilla report 53036 | 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: | Fixed bugs: | ||||
| ----------- | ----------- | ||||
| @@ -36,9 +40,14 @@ Fixed bugs: | |||||
| Other changes: | 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 | 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 | checksum=org.apache.tools.ant.taskdefs.Checksum | ||||
| chmod=org.apache.tools.ant.taskdefs.Chmod | chmod=org.apache.tools.ant.taskdefs.Chmod | ||||
| classloader=org.apache.tools.ant.taskdefs.Classloader | classloader=org.apache.tools.ant.taskdefs.Classloader | ||||
| commandlaucher=org.apache.tools.ant.taskdefs.CommandLauncherTask | |||||
| componentdef=org.apache.tools.ant.taskdefs.Componentdef | componentdef=org.apache.tools.ant.taskdefs.Componentdef | ||||
| concat=org.apache.tools.ant.taskdefs.Concat | concat=org.apache.tools.ant.taskdefs.Concat | ||||
| condition=org.apache.tools.ant.taskdefs.ConditionTask | 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); | |||||
| } | |||||
| } | |||||