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.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.Task; | 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.taskdefs.condition.Os; | ||||
import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
@@ -56,6 +57,9 @@ public class Execute { | |||||
private File workingDirectory = null; | private File workingDirectory = null; | ||||
private Project project = null; | private Project project = null; | ||||
private boolean newEnvironment = false; | 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 */ | /** Controls whether the VM is used to launch commands, where possible */ | ||||
private boolean useVMLauncher = true; | private boolean useVMLauncher = true; | ||||
@@ -64,7 +68,6 @@ public class Execute { | |||||
private static CommandLauncher vmLauncher = null; | private static CommandLauncher vmLauncher = null; | ||||
private static CommandLauncher shellLauncher = null; | private static CommandLauncher shellLauncher = null; | ||||
private static Vector procEnvironment = null; | private static Vector procEnvironment = null; | ||||
private boolean spawn = false; | |||||
/** Used to destroy processes when the VM exits. */ | /** Used to destroy processes when the VM exits. */ | ||||
private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); | private static ProcessDestroyer processDestroyer = new ProcessDestroyer(); | ||||
@@ -75,9 +78,7 @@ public class Execute { | |||||
static { | static { | ||||
// Try using a JDK 1.3 launcher | // Try using a JDK 1.3 launcher | ||||
try { | try { | ||||
if (Os.isFamily("openvms")) { | |||||
vmLauncher = new VmsCommandLauncher(); | |||||
} else if (!Os.isFamily("os/2")) { | |||||
if (!Os.isFamily("os/2")) { | |||||
vmLauncher = new Java13CommandLauncher(); | vmLauncher = new Java13CommandLauncher(); | ||||
} | } | ||||
} catch (NoSuchMethodException exc) { | } catch (NoSuchMethodException exc) { | ||||
@@ -124,8 +125,12 @@ public class Execute { | |||||
shellLauncher | shellLauncher | ||||
= new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); | = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher); | ||||
} else if (Os.isFamily("openvms")) { | } 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 { | } else { | ||||
// Generic | // Generic | ||||
shellLauncher = new ScriptCommandLauncher("bin/antRun", | shellLauncher = new ScriptCommandLauncher("bin/antRun", | ||||
@@ -304,6 +309,11 @@ public class Execute { | |||||
ExecuteWatchdog watchdog) { | ExecuteWatchdog watchdog) { | ||||
setStreamHandler(streamHandler); | setStreamHandler(streamHandler); | ||||
this.watchdog = watchdog; | 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>. | * @param process the <CODE>Process</CODE>. | ||||
*/ | */ | ||||
public static void closeStreams(Process process) { | 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) | private File createCommandFile(String[] cmd, String[] env) | ||||
throws IOException { | 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(); | script.deleteOnExit(); | ||||
PrintWriter out = null; | PrintWriter out = null; | ||||
try { | 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.Assertions; | ||||
import org.apache.tools.ant.types.Permissions; | import org.apache.tools.ant.types.Permissions; | ||||
import org.apache.tools.ant.types.RedirectorElement; | 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 | * Launcher for Java applications. Allows use of | ||||
@@ -732,29 +734,8 @@ public class Java extends Task { | |||||
Execute exe | Execute exe | ||||
= new Execute(redirector.createHandler(), createWatchdog()); | = 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 { | try { | ||||
int rc = exe.execute(); | int rc = exe.execute(); | ||||
redirector.complete(); | redirector.complete(); | ||||
@@ -767,6 +748,8 @@ public class Java extends Task { | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Executes the given classname with the given arguments in a separate VM. | * Executes the given classname with the given arguments in a separate VM. | ||||
*/ | */ | ||||
@@ -774,18 +757,33 @@ public class Java extends Task { | |||||
Execute exe | Execute exe | ||||
= new Execute(); | = 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(); | String[] environment = env.getVariables(); | ||||
if (environment != null) { | if (environment != null) { | ||||
for (int i = 0; i < environment.length; i++) { | for (int i = 0; i < environment.length; i++) { | ||||
@@ -795,14 +793,69 @@ public class Java extends Task { | |||||
} | } | ||||
exe.setNewenvironment(newEnvironment); | exe.setNewenvironment(newEnvironment); | ||||
exe.setEnvironment(environment); | 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 { | 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) { | } 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 | * Executes the given classname with the given arguments as it | ||||
* was a command line application. | * 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.types.Path; | ||||
import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
import org.apache.tools.ant.taskdefs.condition.Os; | |||||
/** | /** | ||||
* This is the default implementation for the CompilerAdapter interface. | * 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", | throw new BuildException("Error creating temporary file", | ||||
e, location); | e, location); | ||||
} finally { | } finally { | ||||
if (out != null) { | |||||
try { | |||||
out.close(); | |||||
} catch (Throwable t) { | |||||
// ignore | |||||
} | |||||
} | |||||
FileUtils.close(out); | |||||
} | } | ||||
} else { | } else { | ||||
commandArray = args; | commandArray = args; | ||||
@@ -433,6 +428,11 @@ public abstract class DefaultCompilerAdapter implements CompilerAdapter { | |||||
new LogStreamHandler(attributes, | new LogStreamHandler(attributes, | ||||
Project.MSG_INFO, | Project.MSG_INFO, | ||||
Project.MSG_WARN)); | 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.setAntRun(project); | ||||
exe.setWorkingDirectory(project.getBaseDir()); | exe.setWorkingDirectory(project.getBaseDir()); | ||||
exe.setCommandline(commandArray); | exe.setCommandline(commandArray); | ||||
@@ -17,9 +17,15 @@ | |||||
package org.apache.tools.ant.taskdefs.compilers; | 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.BuildException; | ||||
import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
import org.apache.tools.ant.types.Commandline; | 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. | * Performs a compile using javac externally. | ||||
@@ -39,11 +45,40 @@ public class JavacExternal extends DefaultCompilerAdapter { | |||||
setupModernJavacCommandlineSwitches(cmd); | setupModernJavacCommandlineSwitches(cmd); | ||||
int firstFileName = assumeJava11() ? -1 : cmd.size(); | int firstFileName = assumeJava11() ? -1 : cmd.size(); | ||||
logAndAddFilesToCompile(cmd); | 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 | 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; | package org.apache.tools.ant.util; | ||||
import java.io.File; | 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 java.util.Vector; | ||||
import org.apache.tools.ant.taskdefs.condition.Os; | import org.apache.tools.ant.taskdefs.condition.Os; | ||||
@@ -28,6 +32,9 @@ import org.apache.tools.ant.taskdefs.condition.Os; | |||||
*/ | */ | ||||
public class JavaEnvUtils { | public class JavaEnvUtils { | ||||
private JavaEnvUtils() { | |||||
} | |||||
/** Are we on a DOS-based system */ | /** Are we on a DOS-based system */ | ||||
private static final boolean isDos = Os.isFamily("dos"); | private static final boolean isDos = Os.isFamily("dos"); | ||||
/** Are we on Novell NetWare */ | /** Are we on Novell NetWare */ | ||||
@@ -115,7 +122,7 @@ public class JavaEnvUtils { | |||||
* @since Ant 1.5 | * @since Ant 1.5 | ||||
*/ | */ | ||||
public static boolean isJavaVersion(String version) { | public static boolean isJavaVersion(String version) { | ||||
return javaVersion == version; | |||||
return javaVersion.equals(version); | |||||
} | } | ||||
/** | /** | ||||
@@ -332,4 +339,29 @@ public class JavaEnvUtils { | |||||
} | } | ||||
return jrePackages; | 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; | |||||
} | |||||
} | } |