📄 execute.java
字号:
private String[] patchEnvironment() { // On OpenVMS Runtime#exec() doesn't support the environment array, // so we only return the new values which then will be set in // the generated DCL script, inheriting the parent process environment if (Os.isFamily("openvms")) { return env; } Vector osEnv = (Vector) getProcEnvironment().clone(); for (int i = 0; i < env.length; i++) { String keyValue = env[i]; // Get key including "=" String key = keyValue.substring(0, keyValue.indexOf('=') + 1); if (environmentCaseInSensitive) { // Nb: using default locale as key is a env name key = key.toLowerCase(); } int size = osEnv.size(); // Find the key in the current enviroment copy // and remove it. for (int j = 0; j < size; j++) { String osEnvItem = (String) osEnv.elementAt(j); String convertedItem = environmentCaseInSensitive ? osEnvItem.toLowerCase() : osEnvItem; if (convertedItem.startsWith(key)) { osEnv.removeElementAt(j); if (environmentCaseInSensitive) { // Use the original casiness of the key keyValue = osEnvItem.substring(0, key.length()) + keyValue.substring(key.length()); } break; } } // Add the key to the enviromnent copy osEnv.addElement(keyValue); } return (String[]) (osEnv.toArray(new String[osEnv.size()])); } /** * A utility method that runs an external command. Writes the output and * error streams of the command to the project log. * * @param task The task that the command is part of. Used for logging * @param cmdline The command to execute. * * @throws BuildException if the command does not exit successfully. */ public static void runCommand(Task task, String[] cmdline) throws BuildException { try { task.log(Commandline.describeCommand(cmdline), Project.MSG_VERBOSE); Execute exe = new Execute( new LogStreamHandler(task, Project.MSG_INFO, Project.MSG_ERR)); exe.setAntRun(task.getProject()); exe.setCommandline(cmdline); int retval = exe.execute(); if (isFailure(retval)) { throw new BuildException(cmdline[0] + " failed with return code " + retval, task.getLocation()); } } catch (java.io.IOException exc) { throw new BuildException("Could not launch " + cmdline[0] + ": " + exc, task.getLocation()); } } /** * Close the streams belonging to the given Process. * @param process the <code>Process</code>. */ public static void closeStreams(Process process) { FileUtils.close(process.getInputStream()); FileUtils.close(process.getOutputStream()); FileUtils.close(process.getErrorStream()); } /** * This method is VMS specific and used by getProcEnvironment(). * * Parses VMS logicals from <code>in</code> and adds them to * <code>environment</code>. <code>in</code> is expected to be the * output of "SHOW LOGICAL". The method takes care of parsing the output * correctly as well as making sure that a logical defined in multiple * tables only gets added from the highest order table. Logicals with * multiple equivalence names are mapped to a variable with multiple * values separated by a comma (,). */ private static Vector addVMSLogicals(Vector environment, BufferedReader in) throws IOException { HashMap logicals = new HashMap(); String logName = null, logValue = null, newLogName; String line = null; // CheckStyle:MagicNumber OFF while ((line = in.readLine()) != null) { // parse the VMS logicals into required format ("VAR=VAL[,VAL2]") if (line.startsWith("\t=")) { // further equivalence name of previous logical if (logName != null) { logValue += "," + line.substring(4, line.length() - 1); } } else if (line.startsWith(" \"")) { // new logical? if (logName != null) { logicals.put(logName, logValue); } int eqIndex = line.indexOf('='); newLogName = line.substring(3, eqIndex - 2); if (logicals.containsKey(newLogName)) { // already got this logical from a higher order table logName = null; } else { logName = newLogName; logValue = line.substring(eqIndex + 3, line.length() - 1); } } } // CheckStyle:MagicNumber ON // Since we "look ahead" before adding, there's one last env var. if (logName != null) { logicals.put(logName, logValue); } for (Iterator i = logicals.keySet().iterator(); i.hasNext();) { String logical = (String) i.next(); environment.add(logical + "=" + logicals.get(logical)); } return environment; } /** * 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. */ private static class 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"); } } /** * A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in * Runtime.exec() command. */ private static class Java13CommandLauncher extends CommandLauncher { private Method myExecWithCWD; public Java13CommandLauncher() throws NoSuchMethodException { // Locate method Runtime.exec(String[] cmdarray, // String[] envp, File dir) myExecWithCWD = Runtime.class.getMethod("exec", new Class[] {String[].class, String[].class, File.class}); } /** * 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. */ 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 (Process) myExecWithCWD.invoke(Runtime.getRuntime(), /* the arguments: */ new Object[] {cmd, env, workingDir}); } catch (InvocationTargetException exc) { Throwable realexc = exc.getTargetException(); if (realexc instanceof ThreadDeath) { throw (ThreadDeath) realexc; } else if (realexc instanceof IOException) { throw (IOException) realexc; } else { throw new BuildException("Unable to execute command", realexc); } } catch (Exception exc) { // IllegalAccess, IllegalArgument, ClassCast throw new BuildException("Unable to execute command", exc); } } } /** * A command launcher that proxies another command launcher. * * Sub-classes override exec(args, env, workdir). */ private static class CommandLauncherProxy extends CommandLauncher { private CommandLauncher myLauncher; 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. */ public Process exec(Project project, String[] cmd, String[] env) throws IOException { return myLauncher.exec(project, cmd, env); } } /** * 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> */ private static class OS2CommandLauncher extends CommandLauncherProxy { 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. */ 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -