This closes #105 pull request at github/apache/ant repomaster
@@ -10,6 +10,10 @@ Fixed bugs: | |||
* sshexec failed to write output to a file if the file didn't exist | |||
* Fixes a regression in javac task involving command line argument | |||
files. | |||
Bugzilla Report 63874 | |||
Other changes: | |||
-------------- | |||
@@ -66,7 +66,7 @@ public class JavacExternal extends DefaultCompilerAdapter { | |||
int firstFileName; | |||
if (assumeJava1_2Plus()) { | |||
firstFileName = moveJOptionsToBeginning(commandLine); | |||
firstFileName = moveArgFileEligibleOptionsToEnd(commandLine); | |||
} else { | |||
firstFileName = -1; | |||
} | |||
@@ -77,31 +77,36 @@ public class JavacExternal extends DefaultCompilerAdapter { | |||
} | |||
/** | |||
* Moves all -J arguments to the beginning | |||
* So that all command line arguments could be written to file, but -J | |||
* Moves all -J and @argfiles arguments to the beginning | |||
* So that all command line arguments could be written to file, but -J and @argfile | |||
* As per javac documentation: | |||
* you can specify one or more files that contain arguments to the javac command (except -J options) | |||
* @param commandLine command line to process | |||
* @return int index of first non -J argument | |||
* @return int index of first argument that could be put into argfile | |||
*/ | |||
private int moveJOptionsToBeginning(String[] commandLine) { | |||
int nonJArgumentIdx = 1; // 0 for javac executable | |||
while(nonJArgumentIdx < commandLine.length && commandLine[nonJArgumentIdx].startsWith("-J")) { | |||
nonJArgumentIdx++; | |||
private int moveArgFileEligibleOptionsToEnd(String[] commandLine) { | |||
int nonArgFileOptionIdx = 1; // 0 for javac executable | |||
while(nonArgFileOptionIdx < commandLine.length && | |||
!isArgFileEligible(commandLine[nonArgFileOptionIdx])) { | |||
nonArgFileOptionIdx++; | |||
} | |||
for(int i = nonJArgumentIdx + 1; i < commandLine.length; i++) { | |||
if (commandLine[i].startsWith("-J")) { | |||
String jArgument = commandLine[i]; | |||
for(int j = i - 1; j >= nonJArgumentIdx; j--) { | |||
for(int i = nonArgFileOptionIdx + 1; i < commandLine.length; i++) { | |||
if (!isArgFileEligible(commandLine[i])) { | |||
String option = commandLine[i]; | |||
for(int j = i - 1; j >= nonArgFileOptionIdx; j--) { | |||
commandLine[j + 1] = commandLine[j]; | |||
} | |||
commandLine[nonJArgumentIdx] = jArgument; | |||
nonJArgumentIdx++; | |||
commandLine[nonArgFileOptionIdx] = option; | |||
nonArgFileOptionIdx++; | |||
} | |||
} | |||
return nonJArgumentIdx; | |||
return nonArgFileOptionIdx; | |||
} | |||
private static boolean isArgFileEligible(String option) { | |||
return !(option.startsWith("-J") || option.startsWith("@")); | |||
} | |||
/** | |||
@@ -28,6 +28,7 @@ import org.junit.Test; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Arrays; | |||
import java.util.stream.Stream; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
@@ -131,6 +132,47 @@ public class JavacExternalTest { | |||
} | |||
} | |||
@Test | |||
public void argFileOptionIsMovedToBeginning() throws Exception { | |||
final File workDir = createWorkDir("testSMC"); | |||
try { | |||
final File src = new File(workDir, "src"); | |||
src.mkdir(); | |||
createFile(src, "org/apache/ant/tests/J1.java"); | |||
createFile(src, "org/apache/ant/tests/J2.java"); | |||
final File modules = new File(workDir, "modules"); | |||
modules.mkdir(); | |||
final Project prj = new Project(); | |||
prj.setBaseDir(workDir); | |||
final Javac javac = new Javac(); | |||
javac.setProject(prj); | |||
final Commandline[] cmd = new Commandline[1]; | |||
final TestJavacExternal impl = new TestJavacExternal(); | |||
final Path srcPath = new Path(prj); | |||
srcPath.setLocation(src); | |||
javac.setSrcdir(srcPath); | |||
javac.createModulepath().setLocation(modules); | |||
javac.setSource("9"); | |||
javac.setTarget("9"); | |||
javac.setFork(true); | |||
javac.setMemoryInitialSize("80m"); | |||
javac.setExecutable("javacExecutable"); | |||
javac.add(impl); | |||
javac.createCompilerArg().setValue("-g"); | |||
javac.createCompilerArg().setValue("@/home/my-compiler.args"); | |||
javac.execute(); | |||
assertEquals("javacExecutable", impl.getArgs()[0]); | |||
assertEquals("-J-Xms80m", impl.getArgs()[1]); | |||
assertEquals("@/home/my-compiler.args", impl.getArgs()[2]); | |||
assertTrue(Stream.of(impl.getArgs()).anyMatch(x -> x.equals("-g"))); | |||
assertTrue(impl.getArgs()[impl.getArgs().length - 2].endsWith("J1.java")); | |||
assertTrue(impl.getArgs()[impl.getArgs().length - 1].endsWith("J2.java")); | |||
assertEquals(3, impl.getFirstFileName()); | |||
} finally { | |||
delete(workDir); | |||
} | |||
} | |||
private File createWorkDir(String testName) { | |||
final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N | |||
final File destDir = new File(tmp, String.format("%s%s%d", | |||