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", | ||||