diff --git a/plexus-compiler-api/src/main/java/org/codehaus/plexus/compiler/AbstractCompiler.java b/plexus-compiler-api/src/main/java/org/codehaus/plexus/compiler/AbstractCompiler.java index 0acb4694f..5957950f9 100644 --- a/plexus-compiler-api/src/main/java/org/codehaus/plexus/compiler/AbstractCompiler.java +++ b/plexus-compiler-api/src/main/java/org/codehaus/plexus/compiler/AbstractCompiler.java @@ -295,4 +295,31 @@ private static String getRelativeWorkingDirectory(CompilerConfiguration config) } return to; } + + /** + * Joins the configured annotation processor names, skipping blank entries. + *

+ * Maven maps an explicitly empty {@code } element to an array holding + * blank strings rather than to an empty array. Passing those on yields {@code -processor} with + * an empty processor name, which no compiler can resolve. Callers should omit the option + * entirely when this returns an empty string. + * + * @param annotationProcessors the configured names, possibly {@code null} + * @return the non-blank names joined by commas, or an empty string if none remain + * @since 2.17.1 + */ + protected static String joinAnnotationProcessors(String[] annotationProcessors) { + StringBuilder buffer = new StringBuilder(); + if (annotationProcessors != null) { + for (String annotationProcessor : annotationProcessors) { + if (annotationProcessor != null && !annotationProcessor.trim().isEmpty()) { + if (buffer.length() > 0) { + buffer.append(','); + } + buffer.append(annotationProcessor); + } + } + } + return buffer.toString(); + } } diff --git a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompiler.java b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompiler.java index 3c7f4f4c1..bee72a0fc 100644 --- a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompiler.java +++ b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EclipseJavaCompiler.java @@ -173,23 +173,16 @@ public CompilerResult performCompile(CompilerConfiguration config) throws Compil } // now add jdk 1.6 annotation processing related parameters - String[] annotationProcessors = config.getAnnotationProcessors(); + String annotationProcessors = joinAnnotationProcessors(config.getAnnotationProcessors()); List processorPathEntries = config.getProcessorPathEntries(); List processorModulePathEntries = config.getProcessorModulePathEntries(); - if ((annotationProcessors != null && annotationProcessors.length > 0) + if (!annotationProcessors.isEmpty() || (processorPathEntries != null && processorPathEntries.size() > 0) || (processorModulePathEntries != null && processorModulePathEntries.size() > 0)) { - if (annotationProcessors != null && annotationProcessors.length > 0) { + if (!annotationProcessors.isEmpty()) { args.add("-processor"); - StringBuilder sb = new StringBuilder(); - for (String ap : annotationProcessors) { - if (sb.length() > 0) { - sb.append(','); - } - sb.append(ap); - } - args.add(sb.toString()); + args.add(annotationProcessors); } if (processorPathEntries != null && processorPathEntries.size() > 0) { diff --git a/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java b/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java index e6f7223e7..f1b18d4ae 100644 --- a/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java +++ b/plexus-compilers/plexus-compiler-javac/src/main/java/org/codehaus/plexus/compiler/javac/JavacCompiler.java @@ -421,17 +421,10 @@ public static String[] buildCompilerArguments( if (config.getProc() != null) { args.add("-proc:" + config.getProc()); } - if (config.getAnnotationProcessors() != null) { + String annotationProcessors = joinAnnotationProcessors(config.getAnnotationProcessors()); + if (!annotationProcessors.isEmpty()) { args.add("-processor"); - String[] procs = config.getAnnotationProcessors(); - StringBuilder buffer = new StringBuilder(); - for (int i = 0; i < procs.length; i++) { - if (i > 0) { - buffer.append(","); - } - buffer.append(procs[i]); - } - args.add(buffer.toString()); + args.add(annotationProcessors); } if (config.getProcessorPathEntries() != null && !config.getProcessorPathEntries().isEmpty()) { diff --git a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/AbstractJavacCompilerTest.java b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/AbstractJavacCompilerTest.java index b3d33045f..d8e906773 100644 --- a/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/AbstractJavacCompilerTest.java +++ b/plexus-compilers/plexus-compiler-javac/src/test/java/org/codehaus/plexus/compiler/javac/AbstractJavacCompilerTest.java @@ -38,6 +38,9 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Jason van Zyl @@ -200,6 +203,61 @@ public void internalTest( assertArrayEquals(actualArguments, expectedArguments.toArray(new String[0])); } + @Test + public void testBuildCompilerArgsEmptyAnnotationProcessors() { + CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + compilerConfiguration.setOutputLocation("/output"); + compilerConfiguration.setAnnotationProcessors(new String[0]); + + String[] actualArguments = JavacCompiler.buildCompilerArguments(compilerConfiguration, new String[0], "17"); + + assertFalse( + Arrays.asList(actualArguments).contains("-processor"), + "an empty processor array must not produce -processor with an empty argument"); + } + + @Test + public void testBuildCompilerArgsBlankAnnotationProcessors() { + CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + compilerConfiguration.setOutputLocation("/output"); + compilerConfiguration.setAnnotationProcessors(new String[] {"", ""}); + + String[] actualArguments = JavacCompiler.buildCompilerArguments(compilerConfiguration, new String[0], "17"); + + assertFalse( + Arrays.asList(actualArguments).contains("-processor"), + "an array of blank processor names must not produce -processor"); + } + + @Test + public void testBuildCompilerArgsMixedBlankAnnotationProcessors() { + CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + compilerConfiguration.setOutputLocation("/output"); + compilerConfiguration.setAnnotationProcessors( + new String[] {"", "com.example.First", " ", "com.example.Second"}); + + List actualArguments = + Arrays.asList(JavacCompiler.buildCompilerArguments(compilerConfiguration, new String[0], "17")); + + int index = actualArguments.indexOf("-processor"); + assertTrue(index >= 0, "-processor must be present when at least one name is not blank"); + assertEquals("com.example.First,com.example.Second", actualArguments.get(index + 1)); + } + + @Test + public void testBuildCompilerArgsAnnotationProcessors() { + CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); + compilerConfiguration.setOutputLocation("/output"); + compilerConfiguration.setAnnotationProcessors(new String[] {"com.example.First", "com.example.Second"}); + + List actualArguments = + Arrays.asList(JavacCompiler.buildCompilerArguments(compilerConfiguration, new String[0], "17")); + + int index = actualArguments.indexOf("-processor"); + assertTrue(index >= 0, "-processor must be present for a non-empty processor array"); + assertEquals("com.example.First,com.example.Second", actualArguments.get(index + 1)); + } + @Test public void testBuildCompilerArgs13() { List expectedArguments = new ArrayList<>();