projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.93k stars 2.4k forks source link

[BUG] In 1.18.22 `@SuperBuilder` + `mapstruct` causes `javadoc` generation to fail. #3004

Open jmax01 opened 3 years ago

jmax01 commented 3 years ago

In 1.18.22 @SuperBuilder + mapstruct causes javadoc generation to fail.

Generation works fine in 1.18.20 but if one switches to .22:

Error while generating Javadoc: 
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.3.1:jar (default-jar) on project lombok-javadoc-issue: MavenReportException: Error while generating Javadoc: 
[ERROR] Exit code: 1 - /Users/jmaxwell/ewksps/setup/lombok-javadoc-issue/target/generated-sources/annotations/lombok/test/javadoc/LombokTest$MyValueType1ToMyValueType2MapperImpl.java:7: error: cannot find symbol
[ERROR] import lombok.test.javadoc.LombokTest.MyValueType2.MyValueType2Builder;
[ERROR]                                                   ^
[ERROR]   symbol:   class MyValueType2Builder
[ERROR]   location: class MyValueType2
[ERROR] 
[ERROR] Command line was: /Library/Java/JavaVirtualMachines/adoptopenjdk-15.jdk/Contents/Home/bin/javadoc @options @packages
[ERROR] 
[ERROR] Refer to the generated Javadoc files in '/Users/jmaxwell/ewksps/setup/lombok-javadoc-issue/target/apidocs' dir.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.

To Reproduce

With the artifacts below run mvn clean install:

Test Class:

package lombok.test.javadoc;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Value;
import lombok.experimental.SuperBuilder;
import org.mapstruct.Mapper;

/**
 * The Class LombokTest.
 */
public class LombokTest {

    /**
     * The Class MyValueType1.
     */
    @Value
    @SuperBuilder
    @AllArgsConstructor(access = AccessLevel.PUBLIC)
    public static final class MyValueType1 {

        /** The my string field. */
        String myStringField;
    }

    /**
     * The Class MyValueType2.
     */
    @Value
    @SuperBuilder
    @AllArgsConstructor(access = AccessLevel.PUBLIC)
    public static final class MyValueType2 {

        /** The my string field. */
        String myStringField;
    }

    /**
     * The Interface MyValueType1ToMyValueType2Mapper.
     */
    @Mapper
    public interface MyValueType1ToMyValueType2Mapper {

        /**
         * My value type 1 to my value type 2.
         *
         * @param myValue1 the my value 1
         *
         * @return the my value type 2
         */
        MyValueType2 myValueType1ToMyValueType2(MyValueType1 myValue1);
    }
}

lombok.config:

lombok.addLombokGeneratedAnnotation = true
lombok.extern.findbugs.addSuppressFBWarnings = true
lombok.log.fieldName = LOGGER
lombok.equalsAndHashCode.callSuper = CALL
lombok.toString.callSuper = CALL

pom:

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok-javadoc-issue</artifactId>
  <version>1.0.0-SNAPSHOT</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <mavenVersion>3.8.3</mavenVersion>

    <java.version>15</java.version>

    <maven-install-plugin.version>3.0.0-M1</maven-install-plugin.version>

    <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
    <maven.compiler.release>${java.version}</maven.compiler.release>
    <maven.compiler.source>${java.version}</maven.compiler.source>
    <maven.compiler.target>${java.version}</maven.compiler.target>
    <maven.compiler.compilerVersion>${java.version}</maven.compiler.compilerVersion>
    <maven.compiler.verbose>true</maven.compiler.verbose>
    <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
    <maven.compiler.showWarnings>true</maven.compiler.showWarnings>
    <maven.compiler.fork>true</maven.compiler.fork>
    <maven.compiler.parameters>true</maven.compiler.parameters>
    <maven.compiler.testSource>${maven.compiler.source}</maven.compiler.testSource>
    <maven.compiler.testTarget>${maven.compiler.target}</maven.compiler.testTarget>
    <maven.compiler.testRelease>${maven.compiler.release}</maven.compiler.testRelease>

    <maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>

    <maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>

    <maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>

    <maven-surefire-plugin.verison>3.0.0-M5</maven-surefire-plugin.verison>
  </properties>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>${maven-resources-plugin.version}</version>
        </plugin>

        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>${maven-install-plugin.version}</version>
        </plugin>

        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>${maven-jar-plugin.version}</version>
        </plugin>

        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven-compiler-plugin.version}</version>
          <configuration>
            <compilerArgs>
              <arg>
                -Amapstruct.suppressGeneratorTimestamp=true
              </arg>
              <arg>
                -Amapstruct.suppressGeneratorVersionInfoComment=true
              </arg>
              <arg>
                -Amapstruct.verbose=true
              </arg>
              <arg>
                -Amapstruct.defaultInjectionStrategy=constructor
              </arg>
            </compilerArgs>
          </configuration>
        </plugin>

        <plugin>
          <artifactId>maven-javadoc-plugin</artifactId>
          <version>${maven-javadoc-plugin.version}</version>
        </plugin>

        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>${maven-surefire-plugin.verison}</version>
        </plugin>
      </plugins>
    </pluginManagement>

    <plugins>
      <plugin>
        <artifactId>maven-javadoc-plugin</artifactId>
        <executions>
          <execution>
            <id>default-jar</id>
            <goals>
              <goal>jar</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
      </dependency>

      <dependency>
        <groupId>com.github.spotbugs</groupId>
        <artifactId>spotbugs-annotations</artifactId>
        <version>4.4.2</version>
      </dependency>

      <dependency>
        <groupId>org.checkerframework</groupId>
        <artifactId>checker-qual</artifactId>
        <version>3.18.1</version>
      </dependency>

      <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <scope>provided</scope>
        <version>1.4.2.Final</version>
      </dependency>

      <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>1.4.2.Final</version>
      </dependency>

      <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-mapstruct-binding</artifactId>
        <version>0.2.0</version>
        <scope>provided</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>com.github.spotbugs</groupId>
      <artifactId>spotbugs-annotations</artifactId>
    </dependency>

    <dependency>
      <groupId>org.checkerframework</groupId>
      <artifactId>checker-qual</artifactId>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct-processor</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.mapstruct</groupId>
      <artifactId>mapstruct</artifactId>
    </dependency>

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok-mapstruct-binding</artifactId>
      <scope>provided</scope>
    </dependency>
  </dependencies>

  <profiles>
    <profile>
      <id>m2e</id>
      <activation>
        <property>
          <name>m2e.version</name>
        </property>
      </activation>

      <build>
        <directory>${project.basedir}/target-eclipse</directory>
      </build>
    </profile>
  </profiles>
</project>

Expected behavior Javadoc generation should not fail.

Version info (please complete the following information):

pafnucy commented 2 years ago

Was able to reproduce with @Builder instead of @SuperBuilder.

Possible fix is updating MapStruct to 1.5.0.Beta2.

Had a similar issue in a Spring Boot application, but it would fail with lombok 1.18.20. Seems like an issue with lombok-mapstruct integration or mapstruct alone.

rzwitserloot commented 2 years ago

Sounds like we can probably just close this issue? I'm not sure we can meaningfully contribute something in the line of a fix; whatever v1.5.0.beta2 is doing that makes this problem go away, that'll be the stable release sooner than we can research this bug.

jmax01 commented 2 years ago

Sounds like we can probably just close this issue? I'm not sure we can meaningfully contribute something in the line of a fix; whatever v1.5.0.beta2 is doing that makes this problem go away, that'll be the stable release sooner than we can research this bug.

I really think this is a lombok issue as I have encountered the same problem without mapstruct in 1.18.20.

In the example below if we directly import MyEntityBuilder the javadoc generation fails:

      //Javadoc generation fails
      import MyEntity.MyEntityBuilder;

      private MyEntity handleSameState(
                final MyEntity existingMyEntity,
                final MyEntityUpdateRequest myEntityUpdateRequest) {

            return myEntityUpdateRequest.notes()
                    .map(existingMyEntity.toBuilder()::notes)
                    .map(MyEntityBuilder::build)
                    .map(myEntity.Repository()::save)
                    .orElse(existingMyEntity);
        }

If we reference MyEntityBuilder via MyEntity javadoc succeeds.

         //Javadoc generation succeeds
        private MyEntity handleSameState(
                final MyEntity existingMyEntity,
                final MyEntityUpdateRequest myEntityUpdateRequest) {

            return myEntityUpdateRequest.notes()
                    .map(existingMyEntity.toBuilder()::notes)
                    .map(MyEntity.MyEntityBuilder::build)
                    .map(myEntity.Repository()::save)
                    .orElse(existingMyEntity);
        }

This does not effect all examples of direct Builder imports (at least in 1.18.20) as mapstruct generated code is properly handled even though it has direct Builder imports.

jmax01 commented 2 years ago

The workaround for this is to add explicit public static class *Builder {} to each affected class.

jmax01 commented 2 years ago

Still fails in 1.18.24

gabrielfq commented 2 years ago

Yes, it works just for @Builder, @SuperBuider I can't do it.

jmax01 commented 2 years ago

It doesn't work on @Builder in 1.18.24

blueSwordfish commented 2 months ago

Did someone figure out how to make it work? I still got the same error. Tried updating the versions of lombok and delombok, and adding this public static class *Builder {} to the code. Neither worked. Any suggestion is much appreciated.