summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bodewig <stefan.bodewig@innoq.com>2022-11-19 17:50:29 +0100
committerStefan Bodewig <stefan.bodewig@innoq.com>2022-11-19 17:50:29 +0100
commit3e6d6acc38a47aa66e629e519f482ee975dd0480 (patch)
tree4408ce95e636cc281cec38adb3b365cbf4e3f5c2
parent0aca73974a1f03afc3f985a4beb94a5cd26e6bcf (diff)
downloadant-3e6d6acc38a47aa66e629e519f482ee975dd0480.tar.gz
paths with wildcards do not work in javac's arg-file
https://bz.apache.org/bugzilla/show_bug.cgi?id=65621
-rw-r--r--WHATSNEW4
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java61
-rw-r--r--src/tests/junit/org/apache/tools/ant/taskdefs/compilers/JavacExternalTest.java42
3 files changed, 98 insertions, 9 deletions
diff --git a/WHATSNEW b/WHATSNEW
index c5a83128b..c4ca47bd7 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -47,6 +47,10 @@ Fixed bugs:
* loadresource might log warnings even though quiet was set to true
Bugzilla Report 65647
+ * javac task would add paths constructs containing wildcards to the
+ internally created argument file where wildcards are not allowed
+ Bugzilla Report 65621
+
Other changes:
--------------
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
index 8ce805900..d4487699c 100644
--- a/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/JavacExternal.java
@@ -20,6 +20,8 @@ package org.apache.tools.ant.taskdefs.compilers;
import java.io.File;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -86,27 +88,68 @@ public class JavacExternal extends DefaultCompilerAdapter {
*/
private int moveArgFileEligibleOptionsToEnd(String[] commandLine) {
int nonArgFileOptionIdx = 1; // 0 for javac executable
- while(nonArgFileOptionIdx < commandLine.length &&
- !isArgFileEligible(commandLine[nonArgFileOptionIdx])) {
- nonArgFileOptionIdx++;
+ while (nonArgFileOptionIdx < commandLine.length) {
+ int argsToMove = numberOfArgsNotEligibleForFile(commandLine, nonArgFileOptionIdx);
+ if (argsToMove > 0) {
+ nonArgFileOptionIdx += argsToMove;
+ } else {
+ break;
+ }
}
for(int i = nonArgFileOptionIdx + 1; i < commandLine.length; i++) {
- if (!isArgFileEligible(commandLine[i])) {
- String option = commandLine[i];
+ int argsToMove = numberOfArgsNotEligibleForFile(commandLine, i);
+ if (argsToMove > 0) {
+ String[] options = Arrays.copyOfRange(commandLine, i, i + argsToMove);
if (i - nonArgFileOptionIdx >= 0) {
- System.arraycopy( commandLine, nonArgFileOptionIdx, commandLine, nonArgFileOptionIdx + 1, i - nonArgFileOptionIdx );
+ System.arraycopy( commandLine, nonArgFileOptionIdx, commandLine, nonArgFileOptionIdx + argsToMove, i - nonArgFileOptionIdx );
}
- commandLine[nonArgFileOptionIdx] = option;
- nonArgFileOptionIdx++;
+ System.arraycopy(options, 0, commandLine, nonArgFileOptionIdx, argsToMove);
+ nonArgFileOptionIdx += argsToMove;
+ i += argsToMove - 1;
}
}
return nonArgFileOptionIdx;
}
+ private static int numberOfArgsNotEligibleForFile(String[] args, int currentIndex) {
+ String currentOption = args[currentIndex];
+ if (!isArgFileEligible(currentOption)) {
+ return 1;
+ }
+ if (currentIndex + 1 < args.length && isArgFollowedByPath(currentOption)
+ && containsWildcards(args[currentIndex + 1])) {
+ return 2;
+ }
+ return 0;
+ }
+
+ private static boolean containsWildcards(String path) {
+ return path.contains("*") || path.contains("?");
+ }
+
private static boolean isArgFileEligible(String option) {
- return !(option.startsWith("-J") || option.startsWith("@"));
+ return !(option.startsWith("-J") || option.startsWith("@")
+ || (option.startsWith("-Xbootclasspath/") && containsWildcards(option))
+ );
+ }
+
+ private static List<String> ARGS_FOLLOWED_BY_PATH = Arrays.asList(
+ "-cp", "-classpath", "--class-path",
+ "-endorseddirs",
+ "-extdirs",
+ "--module-path", "-p",
+ "--module-source-path",
+ "--processor-module-path",
+ "--processor-path", "-processorpath",
+ "-sourcepath", "--source-path",
+ "-bootclasspath", "--boot-class-path",
+ "--upgrade-module-path"
+ );
+
+ private static boolean isArgFollowedByPath(String option) {
+ return ARGS_FOLLOWED_BY_PATH.contains(option);
}
/**
diff --git a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/JavacExternalTest.java b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/JavacExternalTest.java
index a893fb49c..b9874e101 100644
--- a/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/JavacExternalTest.java
+++ b/src/tests/junit/org/apache/tools/ant/taskdefs/compilers/JavacExternalTest.java
@@ -173,6 +173,48 @@ public class JavacExternalTest {
}
}
+ @Test
+ public void classpathWithWildcardsIsMovedToBeginning() 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 Project prj = new Project();
+ prj.setBaseDir(workDir);
+ final File foo = new File(workDir, "foo");
+ foo.mkdir();
+ 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.createClasspath().setPath("foo/*");
+ javac.setSource("9");
+ javac.setTarget("9");
+ javac.setFork(true);
+ javac.setMemoryInitialSize("80m");
+ javac.setExecutable("javacExecutable");
+ javac.add(impl);
+ javac.createCompilerArg().setValue("-g");
+ javac.execute();
+ assertEquals("javacExecutable", impl.getArgs()[0]);
+ assertEquals("-J-Xms80m", impl.getArgs()[1]);
+ assertEquals("-classpath", impl.getArgs()[2]);
+ String normalizedPath = impl.getArgs()[3].replace("\\", "/");
+ assertTrue(normalizedPath + " contains /foo/*", normalizedPath.contains("foo/*"));
+ 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(4, 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",