Took the opportunity to clean up the tasks slightly, such as removing duplication in various methods. We need a unit test for long command line java, and many parameter java, just to see what breaks. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276922 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -33,6 +33,7 @@ import java.util.Vector; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| @@ -56,6 +57,9 @@ public class Execute { | |||
| private File workingDirectory = null; | |||
| private Project project = null; | |||
| private boolean newEnvironment = false; | |||
| //TODO: nothing appears to read this. | |||
| private boolean spawn = false; | |||
| /** Controls whether the VM is used to launch commands, where possible */ | |||
| private boolean useVMLauncher = true; | |||
| @@ -64,7 +68,6 @@ public class Execute { | |||
| private static CommandLauncher vmLauncher = null; | |||
| private static CommandLauncher shellLauncher = null; | |||
| private static Vector procEnvironment = null; | |||
| private boolean spawn = false; | |||
| /** Used to destroy processes when the VM exits. */ | |||
| private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); | |||
| @@ -75,9 +78,7 @@ public class Execute { | |||
| static { | |||
| // Try using a JDK 1.3 launcher | |||
| try { | |||
| if (Os.isFamily("openvms")) { | |||
| vmLauncher = new VmsCommandLauncher(); | |||
| } else if (!Os.isFamily("os/2")) { | |||
| if (!Os.isFamily("os/2")) { | |||
| vmLauncher = new Java13CommandLauncher(); | |||
| } | |||
| } catch (NoSuchMethodException exc) { | |||
| @@ -124,8 +125,12 @@ public class Execute { | |||
| shellLauncher | |||
| = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); | |||
| } else if (Os.isFamily("openvms")) { | |||
| // the vmLauncher already uses the shell | |||
| shellLauncher = vmLauncher; | |||
| // OpenVMS | |||
| try { | |||
| shellLauncher = new VmsCommandLauncher(); | |||
| } catch (NoSuchMethodException exc) { | |||
| // Ignore and keep trying | |||
| } | |||
| } else { | |||
| // Generic | |||
| shellLauncher = new ScriptCommandLauncher("bin/antRun", | |||
| @@ -304,6 +309,11 @@ public class Execute { | |||
| ExecuteWatchdog watchdog) { | |||
| setStreamHandler(streamHandler); | |||
| this.watchdog = watchdog; | |||
| //By default, use the shell launcher for VMS | |||
| // | |||
| if (Os.isFamily("openvms")) { | |||
| useVMLauncher = false; | |||
| } | |||
| } | |||
| /** | |||
| @@ -666,18 +676,9 @@ public class Execute { | |||
| * @param process the <CODE>Process</CODE>. | |||
| */ | |||
| public static void closeStreams(Process process) { | |||
| try { | |||
| process.getInputStream().close(); | |||
| } catch (IOException eyeOhEx) { | |||
| } | |||
| try { | |||
| process.getOutputStream().close(); | |||
| } catch (IOException eyeOhEx) { | |||
| } | |||
| try { | |||
| process.getErrorStream().close(); | |||
| } catch (IOException eyeOhEx) { | |||
| } | |||
| FileUtils.close(process.getInputStream()); | |||
| FileUtils.close(process.getOutputStream()); | |||
| FileUtils.close(process.getErrorStream()); | |||
| } | |||
| /** | |||
| @@ -1151,7 +1152,8 @@ public class Execute { | |||
| */ | |||
| private File createCommandFile(String[] cmd, String[] env) | |||
| throws IOException { | |||
| File script = File.createTempFile("ANT", ".COM"); | |||
| File script = FileUtils.newFileUtils().createTempFile("ANT", ".COM",null); | |||
| //TODO: bind the longevity of the file to the exe | |||
| script.deleteOnExit(); | |||
| PrintWriter out = null; | |||
| try { | |||
| @@ -35,6 +35,8 @@ import org.apache.tools.ant.types.Reference; | |||
| import org.apache.tools.ant.types.Assertions; | |||
| import org.apache.tools.ant.types.Permissions; | |||
| import org.apache.tools.ant.types.RedirectorElement; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| import org.apache.tools.ant.util.JavaEnvUtils; | |||
| /** | |||
| * Launcher for Java applications. Allows use of | |||
| @@ -732,29 +734,8 @@ public class Java extends Task { | |||
| Execute exe | |||
| = new Execute(redirector.createHandler(), createWatchdog()); | |||
| exe.setAntRun(getProject()); | |||
| if (dir == null) { | |||
| dir = getProject().getBaseDir(); | |||
| } else if (!dir.exists() || !dir.isDirectory()) { | |||
| throw new BuildException(dir.getAbsolutePath() | |||
| + " is not a valid directory", | |||
| getLocation()); | |||
| } | |||
| exe.setWorkingDirectory(dir); | |||
| String[] environment = env.getVariables(); | |||
| if (environment != null) { | |||
| for (int i = 0; i < environment.length; i++) { | |||
| log("Setting environment variable: " + environment[i], | |||
| Project.MSG_VERBOSE); | |||
| } | |||
| } | |||
| exe.setNewenvironment(newEnvironment); | |||
| exe.setEnvironment(environment); | |||
| setupExecutable(exe, command); | |||
| exe.setCommandline(command); | |||
| try { | |||
| int rc = exe.execute(); | |||
| redirector.complete(); | |||
| @@ -767,6 +748,8 @@ public class Java extends Task { | |||
| } | |||
| } | |||
| /** | |||
| * Executes the given classname with the given arguments in a separate VM. | |||
| */ | |||
| @@ -774,18 +757,33 @@ public class Java extends Task { | |||
| Execute exe | |||
| = new Execute(); | |||
| exe.setAntRun(getProject()); | |||
| if (dir == null) { | |||
| dir = getProject().getBaseDir(); | |||
| } else if (!dir.exists() || !dir.isDirectory()) { | |||
| throw new BuildException(dir.getAbsolutePath() | |||
| + " is not a valid directory", | |||
| getLocation()); | |||
| setupExecutable(exe, command); | |||
| try { | |||
| exe.spawn(); | |||
| } catch (IOException e) { | |||
| throw new BuildException(e, getLocation()); | |||
| } | |||
| } | |||
| exe.setWorkingDirectory(dir); | |||
| /** | |||
| * Do all configuration for an executable that | |||
| * is common across the {@link #fork(String[])} and | |||
| * {@link #spawn(String[])} methods | |||
| * @param exe executable | |||
| * @param command command to execute | |||
| */ | |||
| private void setupExecutable(Execute exe, String[] command) { | |||
| exe.setAntRun(getProject()); | |||
| setupWorkingDir(exe); | |||
| setupEnvironment(exe); | |||
| setupCommandLine(exe, command); | |||
| } | |||
| /** | |||
| * set up our environment variables | |||
| * @param exe | |||
| */ | |||
| private void setupEnvironment(Execute exe) { | |||
| String[] environment = env.getVariables(); | |||
| if (environment != null) { | |||
| for (int i = 0; i < environment.length; i++) { | |||
| @@ -795,14 +793,69 @@ public class Java extends Task { | |||
| } | |||
| exe.setNewenvironment(newEnvironment); | |||
| exe.setEnvironment(environment); | |||
| } | |||
| /** | |||
| * set the working dir of the new process | |||
| * @param exe | |||
| * @throws BuildException if the dir doesn't exist. | |||
| */ | |||
| private void setupWorkingDir(Execute exe) { | |||
| if (dir == null) { | |||
| dir = getProject().getBaseDir(); | |||
| } else if (!dir.exists() || !dir.isDirectory()) { | |||
| throw new BuildException(dir.getAbsolutePath() | |||
| + " is not a valid directory", | |||
| getLocation()); | |||
| } | |||
| exe.setWorkingDirectory(dir); | |||
| } | |||
| exe.setCommandline(command); | |||
| /** | |||
| * set the command line for the exe. | |||
| * On VMS, hands off to {@link #setupCommandLineForVMS(Execute, String[])} | |||
| * @param exe | |||
| * @param command | |||
| */ | |||
| private void setupCommandLine(Execute exe, String[] command) { | |||
| //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. | |||
| if (Os.isFamily("openvms")) { | |||
| setupCommandLineForVMS(exe, command); | |||
| } else { | |||
| exe.setCommandline(command); | |||
| } | |||
| } | |||
| /** | |||
| * 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 | |||
| * @param command | |||
| */ | |||
| private void setupCommandLineForVMS(Execute exe, String[] command) { | |||
| //Use the VM launcher instead of shell launcher on VMS | |||
| exe.setVMLauncher(true); | |||
| File vmsJavaOptionFile=null; | |||
| try { | |||
| exe.spawn(); | |||
| 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(e, getLocation()); | |||
| throw new BuildException("Failed to create a temporary file for \"-V\" switch"); | |||
| } | |||
| } | |||
| /** | |||
| * Executes the given classname with the given arguments as it | |||
| * was a command line application. | |||
| @@ -31,6 +31,7 @@ import org.apache.tools.ant.types.Commandline; | |||
| import org.apache.tools.ant.types.Path; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.ant.util.JavaEnvUtils; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| /** | |||
| * This is the default implementation for the CompilerAdapter interface. | |||
| @@ -416,13 +417,7 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| throw new BuildException("Error creating temporary file", | |||
| e, location); | |||
| } finally { | |||
| if (out != null) { | |||
| try { | |||
| out.close(); | |||
| } catch (Throwable t) { | |||
| // ignore | |||
| } | |||
| } | |||
| FileUtils.close(out); | |||
| } | |||
| } else { | |||
| commandArray = args; | |||
| @@ -433,6 +428,11 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||
| new LogStreamHandler(attributes, | |||
| Project.MSG_INFO, | |||
| Project.MSG_WARN)); | |||
| if (Os.isFamily("openvms")) { | |||
| //Use the VM launcher instead of shell launcher on VMS | |||
| //for java | |||
| exe.setVMLauncher(true); | |||
| } | |||
| exe.setAntRun(project); | |||
| exe.setWorkingDirectory(project.getBaseDir()); | |||
| exe.setCommandline(commandArray); | |||
| @@ -17,9 +17,15 @@ | |||
| package org.apache.tools.ant.taskdefs.compilers; | |||
| import java.io.IOException; | |||
| import java.io.File; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| import org.apache.tools.ant.util.JavaEnvUtils; | |||
| import org.apache.tools.ant.util.FileUtils; | |||
| /** | |||
| * Performs a compile using javac externally. | |||
| @@ -39,11 +45,40 @@ public class JavacExternal extends DefaultCompilerAdapter { | |||
| setupModernJavacCommandlineSwitches(cmd); | |||
| int firstFileName = assumeJava11() ? -1 : cmd.size(); | |||
| logAndAddFilesToCompile(cmd); | |||
| //On VMS platform, we need to create a special java options file | |||
| //containing the arguments and classpath for the javac command. | |||
| //The special file is supported by the "-V" switch on the VMS JVM. | |||
| if (Os.isFamily("openvms")) { | |||
| return execOnVMS(cmd, firstFileName); | |||
| } | |||
| return | |||
| executeExternalCompile(cmd.getCommandline(), firstFileName, | |||
| true) | |||
| == 0; | |||
| executeExternalCompile(cmd.getCommandline(), firstFileName, | |||
| true) | |||
| == 0; | |||
| } | |||
| /** | |||
| * helper method to execute our command on VMS. | |||
| * @param cmd | |||
| * @param firstFileName | |||
| * @return | |||
| */ | |||
| private boolean execOnVMS(Commandline cmd, int firstFileName) { | |||
| File vmsFile=null; | |||
| try { | |||
| vmsFile = JavaEnvUtils.createVmsJavaOptionFile(cmd.getArguments()); | |||
| String[] commandLine = {cmd.getExecutable(), | |||
| "-V", | |||
| vmsFile.getPath()}; | |||
| return 0==executeExternalCompile(commandLine, | |||
| firstFileName, | |||
| true); | |||
| } catch (IOException e) { | |||
| throw new BuildException("Failed to create a temporary file for \"-V\" switch"); | |||
| } finally { | |||
| FileUtils.delete(vmsFile); | |||
| } | |||
| } | |||
| } | |||
| @@ -1449,5 +1449,15 @@ public class FileUtils { | |||
| } | |||
| } | |||
| /** | |||
| * Delete the file with {@link File#delete()} if the argument is not null. | |||
| * Do nothing on a null argument | |||
| * @param file file to delete | |||
| */ | |||
| public static void delete(File file) { | |||
| if(file!=null) { | |||
| file.delete(); | |||
| } | |||
| } | |||
| } | |||
| @@ -17,6 +17,10 @@ | |||
| package org.apache.tools.ant.util; | |||
| import java.io.File; | |||
| import java.io.IOException; | |||
| import java.io.PrintWriter; | |||
| import java.io.FileWriter; | |||
| import java.io.BufferedWriter; | |||
| import java.util.Vector; | |||
| import org.apache.tools.ant.taskdefs.condition.Os; | |||
| @@ -28,6 +32,9 @@ import org.apache.tools.ant.taskdefs.condition.Os; | |||
| */ | |||
| public class JavaEnvUtils { | |||
| private JavaEnvUtils() { | |||
| } | |||
| /** Are we on a DOS-based system */ | |||
| private static final boolean isDos = Os.isFamily("dos"); | |||
| /** Are we on Novell NetWare */ | |||
| @@ -115,7 +122,7 @@ public class JavaEnvUtils { | |||
| * @since Ant 1.5 | |||
| */ | |||
| public static boolean isJavaVersion(String version) { | |||
| return javaVersion == version; | |||
| return javaVersion.equals(version); | |||
| } | |||
| /** | |||
| @@ -332,4 +339,29 @@ public class JavaEnvUtils { | |||
| } | |||
| return jrePackages; | |||
| } | |||
| /** | |||
| * | |||
| * Writes the command into a temporary DCL script and returns the | |||
| * corresponding File object. | |||
| * It is the job of the caller to delete the file on exit. | |||
| * @param cmd | |||
| * @return | |||
| * @throws IOException | |||
| */ | |||
| public static File createVmsJavaOptionFile(String[] cmd) | |||
| throws IOException { | |||
| File script = FileUtils.newFileUtils() | |||
| .createTempFile("ANT", ".JAVA_OPTS", null); | |||
| PrintWriter out = null; | |||
| try { | |||
| out = new PrintWriter(new BufferedWriter(new FileWriter(script))); | |||
| for (int i = 0; i < cmd.length; i++) { | |||
| out.println(cmd[i]); | |||
| } | |||
| } finally { | |||
| FileUtils.close(out); | |||
| } | |||
| return script; | |||
| } | |||
| } | |||