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 | * 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: | Other changes: | ||||
-------------- | -------------- | ||||
@@ -66,7 +66,7 @@ public class JavacExternal extends DefaultCompilerAdapter { | |||||
int firstFileName; | int firstFileName; | ||||
if (assumeJava1_2Plus()) { | if (assumeJava1_2Plus()) { | ||||
firstFileName = moveJOptionsToBeginning(commandLine); | |||||
firstFileName = moveArgFileEligibleOptionsToEnd(commandLine); | |||||
} else { | } else { | ||||
firstFileName = -1; | 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: | * As per javac documentation: | ||||
* you can specify one or more files that contain arguments to the javac command (except -J options) | * you can specify one or more files that contain arguments to the javac command (except -J options) | ||||
* @param commandLine command line to process | * @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[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.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.stream.Stream; | |||||
import static org.junit.Assert.assertEquals; | import static org.junit.Assert.assertEquals; | ||||
import static org.junit.Assert.assertTrue; | 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) { | private File createWorkDir(String testName) { | ||||
final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N | final File tmp = new File(System.getProperty("java.io.tmpdir")); //NOI18N | ||||
final File destDir = new File(tmp, String.format("%s%s%d", | final File destDir = new File(tmp, String.format("%s%s%d", | ||||