Maven:依赖驱动的 javadoc 聚合和自定义 doclet
Maven: Dependency-driven javadoc aggregation and custom doclet
我已经准备了一个非常简单的演示,演示了我想在更大范围内做些什么来演示这个问题:
配置:java1.8,maven 3.3.9,maven-javadoc-plugin 3.0.1
我有 Maven 工件 testA、testB 和 testC。组件 testA 是一个 javadoc 聚合器项目。 Class B(位于 testB 组件中)导入并实例化 class C(位于 testC 组件中)。
testA 直接依赖于 testB,testB 直接依赖于 testC(两者都提供了作用域),因此 testA 对 testC 具有传递依赖性。
此外,class B 带有自定义 javadoc 标签。
因为我没有编写 doclet 的经验,所以我使用了 doclet I found on the internet 并根据我的需要对其进行了修改(基本上我只是重写了 exclude 方法以仅包括 class 包含自定义标记的文档)。
如上所述,testA 是一个聚合器,旨在仅从直接(非传递)依赖项中收集依赖项源,并仅为标记的 classes 生成 javadoc。这需要任何直接依赖项在构建期间捆绑它们的源代码,因此我使用 maven-source-plugin 从组件 testB 生成源工件。
现在,问题是,当我 运行 maven javadoc 插件时,它因以下异常而失败:
[ERROR] java.lang.ArrayIndexOutOfBoundsException: 0
[ERROR] at com.sun.tools.doclets.formats.html.ConfigurationImpl.setTopFile(ConfigurationImpl.java:537)
异常是指这一行:
this.topFile = DocPath.forPackage(this.packages[0]).resolve(DocPaths.PACKAGE_SUMMARY);
好像没有要处理的包裹。但是,我确信在单个组件上执行时 doclet 会按预期工作(非聚合使用,在没有 maven 的情况下尝试 - javadoc cmd)。当我使用标准 doclet 时,整个聚合也有效,但这对我没有用,因为我真的只需要包含标记的 classes.
这是我的聚合器的 POM.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>testA</artifactId>
<version>1</version>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>testB</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<destDir>testOutput</destDir>
<includeDependencySources>true</includeDependencySources>
<doclet>com.test.MyDoclet</doclet>
<docletArtifact>
<groupId>test</groupId>
<artifactId>my-doclet-artifact</artifactId>
<version>1</version>
</docletArtifact>
<useStandardDocletOptions>true</useStandardDocletOptions>
<tags>
<tag>
<name>MyTag</name>
</tag>
</tags>
</configuration>
</plugin>
</plugins>
</build>
</project>
我做错了什么?有人可以帮帮我吗?
实际上,我设法让它工作了。问题出在 doclet 代码上。我不知道 javadoc 是如何处理代码元素的。
有一个以 RootDoc 节点开头的树结构。从那里它走下这棵树。 RootDoc -> 包 -> 类 -> 成员等。
由于我只处理了标记为 类 的内容,因此其他所有内容都被跳过了。因此,递归在一开始就被破坏了——none 的 PackageDoc 元素通过了条件,所以最后什么都没有处理。
我可以为 javadoc 存储(包括)任何我想要的内容,但无论处理何种类型的元素,我都必须确保递归继续。
我已经准备了一个非常简单的演示,演示了我想在更大范围内做些什么来演示这个问题:
配置:java1.8,maven 3.3.9,maven-javadoc-plugin 3.0.1
我有 Maven 工件 testA、testB 和 testC。组件 testA 是一个 javadoc 聚合器项目。 Class B(位于 testB 组件中)导入并实例化 class C(位于 testC 组件中)。
testA 直接依赖于 testB,testB 直接依赖于 testC(两者都提供了作用域),因此 testA 对 testC 具有传递依赖性。
此外,class B 带有自定义 javadoc 标签。
因为我没有编写 doclet 的经验,所以我使用了 doclet I found on the internet 并根据我的需要对其进行了修改(基本上我只是重写了 exclude 方法以仅包括 class 包含自定义标记的文档)。
如上所述,testA 是一个聚合器,旨在仅从直接(非传递)依赖项中收集依赖项源,并仅为标记的 classes 生成 javadoc。这需要任何直接依赖项在构建期间捆绑它们的源代码,因此我使用 maven-source-plugin 从组件 testB 生成源工件。
现在,问题是,当我 运行 maven javadoc 插件时,它因以下异常而失败:
[ERROR] java.lang.ArrayIndexOutOfBoundsException: 0
[ERROR] at com.sun.tools.doclets.formats.html.ConfigurationImpl.setTopFile(ConfigurationImpl.java:537)
异常是指这一行:
this.topFile = DocPath.forPackage(this.packages[0]).resolve(DocPaths.PACKAGE_SUMMARY);
好像没有要处理的包裹。但是,我确信在单个组件上执行时 doclet 会按预期工作(非聚合使用,在没有 maven 的情况下尝试 - javadoc cmd)。当我使用标准 doclet 时,整个聚合也有效,但这对我没有用,因为我真的只需要包含标记的 classes.
这是我的聚合器的 POM.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>testA</artifactId>
<version>1</version>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<dependency>
<groupId>test</groupId>
<artifactId>testB</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<destDir>testOutput</destDir>
<includeDependencySources>true</includeDependencySources>
<doclet>com.test.MyDoclet</doclet>
<docletArtifact>
<groupId>test</groupId>
<artifactId>my-doclet-artifact</artifactId>
<version>1</version>
</docletArtifact>
<useStandardDocletOptions>true</useStandardDocletOptions>
<tags>
<tag>
<name>MyTag</name>
</tag>
</tags>
</configuration>
</plugin>
</plugins>
</build>
</project>
我做错了什么?有人可以帮帮我吗?
实际上,我设法让它工作了。问题出在 doclet 代码上。我不知道 javadoc 是如何处理代码元素的。
有一个以 RootDoc 节点开头的树结构。从那里它走下这棵树。 RootDoc -> 包 -> 类 -> 成员等。 由于我只处理了标记为 类 的内容,因此其他所有内容都被跳过了。因此,递归在一开始就被破坏了——none 的 PackageDoc 元素通过了条件,所以最后什么都没有处理。
我可以为 javadoc 存储(包括)任何我想要的内容,但无论处理何种类型的元素,我都必须确保递归继续。