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


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


+ 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.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);


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


} }


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

Loading…
Cancel
Save