Browse Source

Somewhat reworked patch for bug# 31106, submitted by Isao Yanagimachi.

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-ffa450edef68
master
Steve Loughran 20 years ago
parent
commit
c31f5ae257
6 changed files with 197 additions and 65 deletions
  1. +21
    -19
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  2. +87
    -34
      src/main/org/apache/tools/ant/taskdefs/Java.java
  3. +7
    -7
      src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
  4. +39
    -4
      src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
  5. +10
    -0
      src/main/org/apache/tools/ant/util/FileUtils.java
  6. +33
    -1
      src/main/org/apache/tools/ant/util/JavaEnvUtils.java

+ 21
- 19
src/main/org/apache/tools/ant/taskdefs/Execute.java View File

@@ -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 {


+ 87
- 34
src/main/org/apache/tools/ant/taskdefs/Java.java View File

@@ -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.


+ 7
- 7
src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java View File

@@ -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);


+ 39
- 4
src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java View File

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

}


+ 10
- 0
src/main/org/apache/tools/ant/util/FileUtils.java View File

@@ -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();
}
}
}


+ 33
- 1
src/main/org/apache/tools/ant/util/JavaEnvUtils.java View File

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

Loading…
Cancel
Save