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; | |||
} | |||
} |