即使没有 (public) Javadoc,如何强制使用 javadoc jar?

How to force a javadoc jar even though there is no (public) Javadoc?

我有一个 Maven 多模块项目,其中一些子模块仅供内部使用。我不想为它发布任何可见的 Javadoc,因为它不应该被第 3 方直接使用。其中没有一个 public 包(包名本身有类似 a.b.c.internal.d 的东西)。

但是,要将 jar 发布到 Maven Central,OSS Sonatype 要求所有库 jar 都有附带的源和 javadoc jar。

如何强制使用固定索引创建 javadoc jar 以告知子模块的用途?想到了一个package-info.java,但是我没有public个packages(所有带"internal"字样的package都被忽略了)。

我发现的一个非常丑陋的解决方法(我不会接受这个答案)是简单地触发一个错误并将出错时失败设置为假。然后 javadoc-plugin 处理一个空的 target/apidocs 文件夹并生成一个空的子模块-javadoc.jar.

我发现最容易触发错误的方法是在/src 根文件夹中创建一个空包-info.java。这会产生以下构建输出:

[INFO] --- maven-javadoc-plugin:3.1.1:jar (attach-javadocs) @ my-internal-module --- [INFO] 1 error [ERROR] MavenReportException: Error while generating Javadoc: Exit code: 1 - javadoc: error - No public or protected classes found to document.

Command line was: "C:\Program Files\Java\jdk1.8.0_131\jre..\bin\javadoc.exe" @options @argfile

Refer to the generated Javadoc files in 'D:\workstation\my-parent-project\modules\my-internal-module\target\apidocs' dir.

org.apache.maven.reporting.MavenReportException: Exit code: 1 - javadoc: error - No public or protected classes found to document.

Command line was: "C:\Program Files\Java\jdk1.8.0_131\jre..\bin\javadoc.exe" @options @argfile

Refer to the generated Javadoc files in 'D:\workstation\my-parent-project\modules\my-internal-module\target\apidocs' dir.

    at org.apache.maven.plugins.javadoc.AbstractJavadocMojo.executeJavadocCommandLine(AbstractJavadocMojo.java:5763)
    at org.apache.maven.plugins.javadoc.AbstractJavadocMojo.executeReport(AbstractJavadocMojo.java:2152)
    at org.apache.maven.plugins.javadoc.JavadocJar.doExecute(JavadocJar.java:189)
    at org.apache.maven.plugins.javadoc.AbstractJavadocMojo.execute(AbstractJavadocMojo.java:1911)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:154)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:146)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:309)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:194)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:107)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:993)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:345)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:191)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)

[INFO] Building jar: D:\workstation\my-parent-project\modules\my-internal-module\target\my-internal-module-6.0.0.beta-SNAPSHOT.2-javadoc.jar

使用以下插件配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
        <execution>
            <id>attach-javadocs</id>
            <goals>
                <goal>jar</goal>
            </goals>
            <phase>package</phase>
            <configuration>
                <show>public</show>
                <failOnError>false</failOnError>
                <detectOfflineLinks>false</detectOfflineLinks>
                <doclint>all,-missing</doclint>
                <nohelp>true</nohelp>
                <excludePackageNames>*.internal.*,testutil,demo</excludePackageNames>
                <quiet>true</quiet>
            </configuration>
        </execution>
    </executions>
    <configuration>
        <failOnError>false</failOnError>
    </configuration>
</plugin>

虽然这满足了我的主要需求(以一种非常丑陋的方式),但我更喜欢带有一个主要自定义条目的 javadoc,我在其中解释了模块的用途。

不要使用 Javadoc 工具生成包含非标准内容的 jar:请使用 maven-jar-plugin 手动创建一个。

初始解取自https://vzurczak.wordpress.com/2014/08/01/generate-an-empty-javadoc-jar-file/

这是我确定的最终解决方案,当在父 pom 中配置时,它通常适用于所有子模块:

定义两个配置文件:

  • 如果子模块中没有自定义 javadoc 文件夹(缺少 src/main/javadoc),则执行标准 javadoc 插件
  • 如果子模块中存在自定义 javadoc 文件夹(src/main/javadoc 存在),则通过 jar 插件执行自定义 javadoc

Maven 配置:

<profiles>
    <profile>
        <id>standard-javadoc</id>
        <activation>
            <file><missing>src/main/javadoc</missing></file>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-javadoc-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>attach-javadocs</id>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                            <phase>package</phase>
                            <configuration>
                                <show>public</show>
                                <failOnError>false</failOnError>
                                <detectOfflineLinks>false</detectOfflineLinks>
                                <doclint>all,-missing</doclint>
                                <nohelp>true</nohelp>
                                <excludePackageNames>*.internal.*,testutil,demo</excludePackageNames>
                                <quiet>true</quiet>
                            </configuration>
                        </execution>
                    </executions>
                    <configuration>
                        <failOnError>false</failOnError>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    </profile>

    <profile>
        <id>custom-javadoc</id>
        <activation>
            <file><exists>src/main/javadoc</exists></file>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <goals>
                                <goal>jar</goal>
                            </goals>
                            <configuration>
                                <classifier>javadoc</classifier>
                                <classesDirectory>${project.basedir}/src/main/javadoc</classesDirectory>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>