使用 Lombok 的 @Builder 注释时出现 Javadoc "cannot find symbol" 错误

Javadoc "cannot find symbol" error when using Lombok's @Builder annotation

我有一个 class 如下所示:

@Data
@Builder
public class Foo {
    private String param;

    /** My custom builder.*/
    public static FooBuilder builder(String _param){
        return builder().param(_param);
    }
}

我收到以下错误:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:2.10.4:javadoc (default-cli) on project foo: An error has occurred in JavaDocs report generation:
[ERROR] Exit code: 1 - /home/workspace/foo/src/main/java/com/foo/Foo.java:34: error: cannot find symbol
[ERROR] public static FooBuilder builder(String _param)
[ERROR] ^
[ERROR] symbol: class FooBuilder
[ERROR] location: class Foo

为了解决这个问题,我不得不使用 Lombok 的 delombok 特性(cf : https://projectlombok.org/features/delombok)。

lombok doesn't cover all tools. For example, lombok cannot plug into javadoc ... which run on java sources. Delombok still allows you to use lombok with these tools by preprocessing your java code into java code with all of lombok's transformations already applied.

我通过添加以下插件使用 Maven 做到了这一点:

<plugin>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-maven-plugin</artifactId>
    <version>1.18.0.0</version>
    <configuration>
        <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
        <outputDirectory>${delombok.output}</outputDirectory>
        <addOutputDirectory>false</addOutputDirectory>
    </configuration>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>delombok</goal>
            </goals>
        </execution>
    </executions>
</plugin>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.9</version>
    <configuration>
        <sourcepath>${delombok.output}</sourcepath>
    </configuration>
</plugin>

Lombok 实际上能够填充部分定义的构建器 class,因此您可以声明足够多的构建器以使 Javadoc 满意并将其留在那里。无需 delombok。

在这种情况下,以下方法对我有用:

@Data
@Builder
public class Foo {
    private String param;

    /** My custom builder.*/
    public static FooBuilder builder(String _param){
        return builder().param(_param);
    }

    // Add this line and all is good
    public static class FooBuilder {}

}

旁注:您实际上可以使用此技术来添加一些客户生成器方法,因此它有好处。当我有集合时,我喜欢重载构建器方法,这样我一次可以一个项目。可能已经有一些技术可以做到这一点,但很高兴知道您可以手动改进构建器。

这是我喜欢做的一件常见事情:

@Builder
public class Foo {
    private final String command;
    private final List<String> params;
    private final boolean background;
    
    public static class FooBuilder {
        public FooBuilder params(final String... params) {
            this.params = Arrays.asList(params);
            return this;
        }
    }
}

在上面 params 生成器方法已被自定义为采用 var args。另一个构建器方法仍将由 Lombok 创建。

更新

如果你使用 maven-javadoc-plugin 3.2.0+,你可以这样配置:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.2.0</version>
    <configuration>
      <doclint>none</doclint>
    </configuration>
  </plugin>

doclint 配置将使 javadoc 插件不再抛出错误。它还会禁用 lint,但如果您对此表示满意,这可能是代替 delombok 的最佳方式。

如果您使用任何 CI 工具来构建和编译您的项目,您可以创建一个单独的作业来检查 javadoc lint。

对我来说,在构建中禁用 lint 并不是一件坏事。 Javadoc 很重要,但不应该因为我正在使用 Lombok 而阻止我构建我的应用程序。