Browse Source

PR 52706: allow command launcher to be selected via a task. Submitted by Vimil Saju

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@1350460 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 13 years ago
parent
commit
abec7e48ef
13 changed files with 826 additions and 582 deletions
  1. +12
    -3
      WHATSNEW
  2. +33
    -0
      src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java
  3. +61
    -579
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  4. +1
    -0
      src/main/org/apache/tools/ant/taskdefs/defaults.properties
  5. +184
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java
  6. +37
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java
  7. +53
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java
  8. +47
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java
  9. +65
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java
  10. +73
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java
  11. +71
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java
  12. +128
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java
  13. +61
    -0
      src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java

+ 12
- 3
WHATSNEW View File

@@ -10,6 +10,10 @@ Changes that could break older environments:
EOL ASIS will not insert a newline even if fixlast is set to true.
Bugzilla report 53036

* The CommandLauncher hierarchy that used to be a set of inner
classes of Execute has been extracted to the
org.apache.tools.ant.taskdefs.launcher package.

Fixed bugs:
-----------

@@ -36,9 +40,14 @@ Fixed bugs:
Other changes:
--------------

* merged the ZIP package from Commons Compress, it can now read
archives using Zip64 extensions (files and archives bigger that 4GB
and with more that 64k entries).
* merged the ZIP package from Commons Compress, it can now read
archives using Zip64 extensions (files and archives bigger that 4GB
and with more that 64k entries).

* a new task <commandlaucher> can be used to configure the
CommandLauncher used by Ant when forking external programs or new
Java VMs.
Bugzilla Report 52706.

Changes from Ant 1.8.3 TO Ant 1.8.4
===================================


+ 33
- 0
src/main/org/apache/tools/ant/taskdefs/CommandLauncherTask.java View File

@@ -0,0 +1,33 @@
package org.apache.tools.ant.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.launcher.CommandLauncher;

public class CommandLauncherTask extends Task {
private boolean vmLauncher;
private CommandLauncher commandLauncher;

public synchronized void addConfigured(CommandLauncher commandLauncher) {
if (this.commandLauncher != null) {
throw new BuildException("Only one CommandLauncher can be installed");
}
this.commandLauncher = commandLauncher;
}

@Override
public void execute() {
if (commandLauncher != null) {
if (vmLauncher) {
CommandLauncher.setVMLauncher(getProject(), commandLauncher);
} else {
CommandLauncher.setShellLauncher(getProject(), commandLauncher);
}
}
}

public void setVmLauncher(boolean vmLauncher) {
this.vmLauncher = vmLauncher;
}

}

+ 61
- 579
src/main/org/apache/tools/ant/taskdefs/Execute.java
File diff suppressed because it is too large
View File


+ 1
- 0
src/main/org/apache/tools/ant/taskdefs/defaults.properties View File

@@ -30,6 +30,7 @@ bzip2=org.apache.tools.ant.taskdefs.BZip2
checksum=org.apache.tools.ant.taskdefs.Checksum
chmod=org.apache.tools.ant.taskdefs.Chmod
classloader=org.apache.tools.ant.taskdefs.Classloader
commandlaucher=org.apache.tools.ant.taskdefs.CommandLauncherTask
componentdef=org.apache.tools.ant.taskdefs.Componentdef
concat=org.apache.tools.ant.taskdefs.Concat
condition=org.apache.tools.ant.taskdefs.ConditionTask


+ 184
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncher.java View File

@@ -0,0 +1,184 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.util.FileUtils;

/**
* A command launcher for a particular JVM/OS platform. This class is
* a general purpose command launcher which can only launch commands
* in the current working directory.
*/
public class CommandLauncher {
private static final String ANT_SHELL_LAUNCHER_REF_ID = "ant.shellLauncher";
private static final String ANT_VM_LAUNCHER_REF_ID = "ant.vmLauncher";

protected static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

private static CommandLauncher vmLauncher = null;
private static CommandLauncher shellLauncher = null;

static {
// Try using a JDK 1.3 launcher
try {
if(!Os.isFamily("os/2")) {
vmLauncher = new Java13CommandLauncher();
}
} catch(NoSuchMethodException exc) {
// Ignore and keep trying
}

if (Os.isFamily("mac") && !Os.isFamily("unix")) {
// Mac
shellLauncher = new MacCommandLauncher(new CommandLauncher());
} else if (Os.isFamily("os/2")) {
// OS/2
shellLauncher = new OS2CommandLauncher(new CommandLauncher());
} else if (Os.isFamily("windows")) {
CommandLauncher baseLauncher = new CommandLauncher();

if (!Os.isFamily("win9x")) {
// Windows XP/2000/NT
shellLauncher = new WinNTCommandLauncher(baseLauncher);
} else {
// Windows 98/95 - need to use an auxiliary script
shellLauncher = new ScriptCommandLauncher("bin/antRun.bat", baseLauncher);
}
} else if (Os.isFamily("netware")) {

CommandLauncher baseLauncher = new CommandLauncher();

shellLauncher = new PerlScriptCommandLauncher("bin/antRun.pl", baseLauncher);
} else if (Os.isFamily("openvms")) {
// OpenVMS
try {
shellLauncher = new VmsCommandLauncher();
} catch(NoSuchMethodException exc) {
// Ignore and keep trying
}
} else {
// Generic
shellLauncher = new ScriptCommandLauncher("bin/antRun", new CommandLauncher());
}
}

/**
* Launches the given command in a new process.
*
* @param project
* The project that the command is part of.
* @param cmd
* The command to execute.
* @param env
* The environment for the new process. If null, the
* environment of the current process is used.
* @return the created Process.
* @throws IOException
* if attempting to run a command in a specific directory.
*/
public Process exec(Project project, String[] cmd, String[] env) throws IOException {
if(project != null) {
project.log("Execute:CommandLauncher: " + Commandline.describeCommand(cmd), Project.MSG_DEBUG);
}
return Runtime.getRuntime().exec(cmd, env);
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* The project that the command is part of.
* @param cmd
* The command to execute.
* @param env
* The environment for the new process. If null, the
* environment of the current process is used.
* @param workingDir
* The directory to start the command in. If null, the
* current directory is used.
* @return the created Process.
* @throws IOException
* if trying to change directory.
*/
public Process exec(Project project, String[] cmd, String[] env, File workingDir) throws IOException {
if(workingDir == null) {
return exec(project, cmd, env);
}
throw new IOException("Cannot execute a process in different "
+ "directory under this JVM");
}

public static CommandLauncher getShellLauncher(Project project) {
CommandLauncher launcher = null;
if(project != null) {
launcher = (CommandLauncher) project
.getReference(ANT_SHELL_LAUNCHER_REF_ID);
}
if (launcher == null) {
launcher = getSystemLauncher(ANT_SHELL_LAUNCHER_REF_ID);
}
if (launcher == null) {
launcher = shellLauncher;
}

return launcher;
}

public static CommandLauncher getVMLauncher(Project project) {
CommandLauncher launcher = null;
if (project != null) {
launcher = (CommandLauncher)project.getReference(ANT_VM_LAUNCHER_REF_ID);
}

if (launcher == null) {
launcher = getSystemLauncher(ANT_VM_LAUNCHER_REF_ID);
}
if (launcher == null) {
launcher = vmLauncher;
}
return launcher;
}

private static CommandLauncher getSystemLauncher(String launcherRefId) {
CommandLauncher launcher = null;
String launcherClass = System.getProperty(launcherRefId);
if (launcherClass != null) {
try {
launcher = (CommandLauncher) Class.forName(launcherClass)
.newInstance();
}
catch(InstantiationException e) {
System.err.println("Could not instantiate launcher class "
+ launcherClass + ": " + e.getMessage());
}
catch(IllegalAccessException e) {
System.err.println("Could not instantiate launcher class "
+ launcherClass + ": " + e.getMessage());
}
catch(ClassNotFoundException e) {
System.err.println("Could not instantiate launcher class "
+ launcherClass + ": " + e.getMessage());
}
}

return launcher;
}

public static void setVMLauncher(Project project, CommandLauncher launcher) {
if (project != null) {
project.addReference(ANT_VM_LAUNCHER_REF_ID, launcher);
}
}

public static void setShellLauncher(Project project, CommandLauncher launcher) {
if (project != null) {
project.addReference(ANT_SHELL_LAUNCHER_REF_ID, launcher);
}
}

}

+ 37
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/CommandLauncherProxy.java View File

@@ -0,0 +1,37 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.IOException;

import org.apache.tools.ant.Project;

/**
* A command launcher that proxies another command
* launcher. Sub-classes override exec(args, env, workdir).
*/
public class CommandLauncherProxy extends CommandLauncher {
private final CommandLauncher myLauncher;

protected CommandLauncherProxy(CommandLauncher launcher) {
myLauncher = launcher;
}

/**
* Launches the given command in a new process. Delegates this
* method to the proxied launcher.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env)
throws IOException {
return myLauncher.exec(project, cmd, env);
}
}

+ 53
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/Java13CommandLauncher.java View File

@@ -0,0 +1,53 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Commandline;

/**
* A command launcher for JDK/JRE 1.3 (and higher). Uses the built-in
* Runtime.exec() command.
*/
public class Java13CommandLauncher extends CommandLauncher {

public Java13CommandLauncher() throws NoSuchMethodException {
// Used to verify if Java13 is available, is prerequisite in ant 1.8
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* the working directory where the command should run.
* @return the created Process.
* @throws IOException
* probably forwarded from Runtime#exec.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
try {
if (project != null) {
project.log("Execute:Java13CommandLauncher: "
+ Commandline.describeCommand(cmd),
Project.MSG_DEBUG);
}
return Runtime.getRuntime().exec(cmd, env, workingDir);
} catch(IOException ioex) {
throw ioex;
} catch(Exception exc) {
// IllegalAccess, IllegalArgument, ClassCast
throw new BuildException("Unable to execute command", exc);
}
}
}

+ 47
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/MacCommandLauncher.java View File

@@ -0,0 +1,47 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.Project;

/**
* A command launcher for Mac that uses a dodgy mechanism to change
* working directory before launching commands.
*/
public class MacCommandLauncher extends CommandLauncherProxy {
public MacCommandLauncher(CommandLauncher launcher) {
super(launcher);
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
if (workingDir == null) {
return exec(project, cmd, env);
}
System.getProperties().put("user.dir", workingDir.getAbsolutePath());
try {
return exec(project, cmd, env);
}
finally {
System.getProperties().put("user.dir", System.getProperty("user.dir"));
}
}
}

+ 65
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/OS2CommandLauncher.java View File

@@ -0,0 +1,65 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.Project;

/**
* A command launcher for OS/2 that uses 'cmd.exe' when launching
* commands in directories other than the current working directory.
*
* <p>Unlike Windows NT and friends, OS/2's cd doesn't support the /d
* switch to change drives and directories in one go.</p>
*/
public class OS2CommandLauncher extends CommandLauncherProxy {
public OS2CommandLauncher(CommandLauncher launcher) {
super(launcher);
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
File commandDir = workingDir;
if (workingDir == null) {
if (project != null) {
commandDir = project.getBaseDir();
} else {
return exec(project, cmd, env);
}
}
// Use cmd.exe to change to the specified drive and
// directory before running the command
final int preCmdLength = 7;
final String cmdDir = commandDir.getAbsolutePath();
String[] newcmd = new String[cmd.length + preCmdLength];
// CheckStyle:MagicNumber OFF - do not bother
newcmd[0] = "cmd";
newcmd[1] = "/c";
newcmd[2] = cmdDir.substring(0, 2);
newcmd[3] = "&&";
newcmd[4] = "cd";
newcmd[5] = cmdDir.substring(2);
newcmd[6] = "&&";
// CheckStyle:MagicNumber ON
System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length);

return exec(project, newcmd, env);
}
}

+ 73
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/PerlScriptCommandLauncher.java View File

@@ -0,0 +1,73 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;

/**
* A command launcher that uses an auxiliary perl script to launch
* commands in directories other than the current working directory.
*/
public class PerlScriptCommandLauncher extends CommandLauncherProxy {
private final String myScript;

public PerlScriptCommandLauncher(String script, CommandLauncher launcher) {
super(launcher);
myScript = script;
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
if (project == null) {
if(workingDir == null) {
return exec(project, cmd, env);
}
throw new IOException("Cannot locate antRun script: "
+ "No project provided");
}
// Locate the auxiliary script
String antHome = project.getProperty(MagicNames.ANT_HOME);
if (antHome == null) {
throw new IOException("Cannot locate antRun script: "
+ "Property '" + MagicNames.ANT_HOME
+ "' not found");
}
String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
antHome + File.separator
+ myScript).toString();

// Build the command
File commandDir = workingDir;
if (workingDir == null) {
commandDir = project.getBaseDir();
}
// CheckStyle:MagicNumber OFF
String[] newcmd = new String[cmd.length + 3];
newcmd[0] = "perl";
newcmd[1] = antRun;
newcmd[2] = commandDir.getAbsolutePath();
System.arraycopy(cmd, 0, newcmd, 3, cmd.length);
// CheckStyle:MagicNumber ON

return exec(project, newcmd, env);
}
}

+ 71
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/ScriptCommandLauncher.java View File

@@ -0,0 +1,71 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.MagicNames;
import org.apache.tools.ant.Project;

/**
* A command launcher that uses an auxiliary script to launch commands
* in directories other than the current working directory.
*/
public class ScriptCommandLauncher extends CommandLauncherProxy {
private final String myScript;

public ScriptCommandLauncher(String script, CommandLauncher launcher) {
super(launcher);
myScript = script;
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
if (project == null) {
if (workingDir == null) {
return exec(project, cmd, env);
}
throw new IOException("Cannot locate antRun script: "
+ "No project provided");
}
// Locate the auxiliary script
String antHome = project.getProperty(MagicNames.ANT_HOME);
if(antHome == null) {
throw new IOException("Cannot locate antRun script: "
+ "Property '" + MagicNames.ANT_HOME
+ "' not found");
}
String antRun = FILE_UTILS.resolveFile(project.getBaseDir(),
antHome + File.separator
+ myScript).toString();

// Build the command
File commandDir = workingDir;
if(workingDir == null) {
commandDir = project.getBaseDir();
}
String[] newcmd = new String[cmd.length + 2];
newcmd[0] = antRun;
newcmd[1] = commandDir.getAbsolutePath();
System.arraycopy(cmd, 0, newcmd, 2, cmd.length);

return exec(project, newcmd, env);
}

}

+ 128
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/VmsCommandLauncher.java View File

@@ -0,0 +1,128 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.util.FileUtils;

/**
* A command launcher for VMS that writes the command to a temporary
* DCL script before launching commands. This is due to limitations of
* both the DCL interpreter and the Java VM implementation.
*/
public class VmsCommandLauncher extends Java13CommandLauncher {

public VmsCommandLauncher() throws NoSuchMethodException {
super();
}

/**
* Launches the given command in a new process.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env)
throws IOException {
File cmdFile = createCommandFile(cmd, env);
Process p = super.exec(project, new String[] {cmdFile.getPath()}, env);
deleteAfter(cmdFile, p);
return p;
}

/**
* Launches the given command in a new process, in the given
* working directory. Note that under Java 1.4.0 and 1.4.1 on VMS
* this method only works if <code>workingDir</code> is null or
* the logical JAVA$FORK_SUPPORT_CHDIR needs to be set to TRUE.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
File cmdFile = createCommandFile(cmd, env);
Process p = super.exec(project, new String[] {
cmdFile.getPath()
}, env, workingDir);
deleteAfter(cmdFile, p);
return p;
}

/*
* Writes the command into a temporary DCL script and returns the
* corresponding File object. The script will be deleted on exit.
* @param cmd the command line to execute as an array of strings.
* @param env the environment to set as an array of strings.
* @return the command File.
* @throws IOException if errors are encountered creating the file.
*/
private File createCommandFile(String[] cmd, String[] env)
throws IOException {
File script = FILE_UTILS.createTempFile("ANT", ".COM", null, true, true);
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(script));

// add the environment as logicals to the DCL script
if (env != null) {
int eqIndex;
for (int i = 0; i < env.length; i++) {
eqIndex = env[i].indexOf('=');
if (eqIndex != -1) {
out.write("$ DEFINE/NOLOG ");
out.write(env[i].substring(0, eqIndex));
out.write(" \"");
out.write(env[i].substring(eqIndex + 1));
out.write('\"');
out.newLine();
}
}
}
out.write("$ " + cmd[0]);
for (int i = 1; i < cmd.length; i++) {
out.write(" -");
out.newLine();
out.write(cmd[i]);
}
} finally {
FileUtils.close(out);
}
return script;
}

private void deleteAfter(final File f, final Process p) {
new Thread() {
@Override
public void run() {
try {
p.waitFor();
} catch(InterruptedException e) {
// ignore
}
FileUtils.delete(f);
}
}.start();
}
}

+ 61
- 0
src/main/org/apache/tools/ant/taskdefs/launcher/WinNTCommandLauncher.java View File

@@ -0,0 +1,61 @@
package org.apache.tools.ant.taskdefs.launcher;

import java.io.File;
import java.io.IOException;

import org.apache.tools.ant.Project;

/**
* A command launcher for Windows XP/2000/NT that uses 'cmd.exe' when
* launching commands in directories other than the current working
* directory.
*/
public class WinNTCommandLauncher extends CommandLauncherProxy {
public WinNTCommandLauncher(CommandLauncher launcher) {
super(launcher);
}

/**
* Launches the given command in a new process, in the given
* working directory.
*
* @param project
* the Ant project.
* @param cmd
* the command line to execute as an array of strings.
* @param env
* the environment to set as an array of strings.
* @param workingDir
* working directory where the command should run.
* @return the created Process.
* @throws IOException
* forwarded from the exec method of the command launcher.
*/
@Override
public Process exec(Project project, String[] cmd, String[] env,
File workingDir) throws IOException {
File commandDir = workingDir;
if (workingDir == null) {
if (project != null) {
commandDir = project.getBaseDir();
} else {
return exec(project, cmd, env);
}
}
// Use cmd.exe to change to the specified directory before running
// the command
final int preCmdLength = 6;
String[] newcmd = new String[cmd.length + preCmdLength];
// CheckStyle:MagicNumber OFF - do not bother
newcmd[0] = "cmd";
newcmd[1] = "/c";
newcmd[2] = "cd";
newcmd[3] = "/d";
newcmd[4] = commandDir.getAbsolutePath();
newcmd[5] = "&&";
// CheckStyle:MagicNumber ON
System.arraycopy(cmd, 0, newcmd, preCmdLength, cmd.length);

return exec(project, newcmd, env);
}
}

Loading…
Cancel
Save