You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sl...@apache.org on 2026/09/11 22:16:52 UTC

(maven-plugin-tools) 10/10: MPLUGIN-421: make the QDox javadoc extractor skip unparseable sources

This is an automated email from the ASF dual-hosted git repository.

slachiewicz pushed a commit to branch maven-plugin-tools-3.x
in repository https://gitbox.apache.org/repos/asf/maven-plugin-tools.git

commit 273ba4f9c10318272391aae8e653739cfadbbb69
Author: Sylwester Lachiewicz <sl...@apache.org>
AuthorDate: Fri Sep 11 20:57:12 2026 +0200

    MPLUGIN-421: make the QDox javadoc extractor skip unparseable sources
    
    3.x still runs the legacy java-javadoc (QDox) extractor alongside the
    now-JavaParser-based java-annotations extractor over the same source
    roots. QDox's addSourceTree() aborts the whole tree on the first file
    it can't parse, so the mplugin-421 IT's comment-only source -- added by
    this series specifically to prove the annotations extractor tolerates
    such files -- broke the QDox extractor's scan and failed CI.
    
    Walk each source tree ourselves and add files to QDox one at a time,
    skipping (with a warning) any file it can't parse, matching the
    tolerance already added to the JavaParser-based JavaSourceModel.
---
 .../JavaJavadocMojoDescriptorExtractor.java        | 31 ++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/javadoc/JavaJavadocMojoDescriptorExtractor.java b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/javadoc/JavaJavadocMojoDescriptorExtractor.java
index 60ad5dff..818dc9f3 100644
--- a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/javadoc/JavaJavadocMojoDescriptorExtractor.java
+++ b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/javadoc/JavaJavadocMojoDescriptorExtractor.java
@@ -22,14 +22,18 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeMap;
+import java.util.stream.Stream;
 
 import com.thoughtworks.qdox.JavaProjectBuilder;
 import com.thoughtworks.qdox.library.SortedClassLibraryBuilder;
@@ -553,19 +557,42 @@ public class JavaJavadocMojoDescriptorExtractor implements MojoDescriptorExtract
             // cannot be controlled, etc.)
             File sourceFile = new File(source);
             if (!request.isExcludedScanDirectory(sourceFile)) {
-                builder.addSourceTree(sourceFile);
+                addSourceTree(builder, sourceFile);
             }
         }
 
         // TODO be more dynamic
         File generatedPlugin = new File(project.getBasedir(), "target/generated-sources/plugin");
         if (!project.getCompileSourceRoots().contains(generatedPlugin.getAbsolutePath())) {
-            builder.addSourceTree(generatedPlugin);
+            addSourceTree(builder, generatedPlugin);
         }
 
         return builder.getClasses();
     }
 
+    /**
+     * Adds every {@code .java} file under {@code sourceTree} to {@code builder} one at a time, skipping
+     * (with a warning) any file QDox cannot parse instead of aborting the whole tree, since a single
+     * unparseable file -- e.g. one containing only comments, or using syntax QDox does not support --
+     * would otherwise hide every mojo declared elsewhere in the tree.
+     */
+    private void addSourceTree(JavaProjectBuilder builder, File sourceTree) {
+        if (!sourceTree.isDirectory()) {
+            return;
+        }
+        try (Stream<Path> paths = Files.walk(sourceTree.toPath())) {
+            paths.filter(path -> path.toString().endsWith(".java")).forEach(path -> {
+                try {
+                    builder.addSource(path.toFile());
+                } catch (IOException | RuntimeException e) {
+                    LOGGER.warn("Unable to parse {}. Javadoc from this source file will be skipped.", path, e);
+                }
+            });
+        } catch (IOException e) {
+            LOGGER.warn("Unable to scan source tree {}", sourceTree, e);
+        }
+    }
+
     /**
      * @param mojoDescriptor not null
      * @throws InvalidParameterException if any