Using MapStruct together with Lombok under Quarkus
Asked Answered
S

3

6

I'm following the guide at the MapStruct blog and having trouble using this 3 technology together. I've been trying several approaches from the MapStruct docs, bug-reports, posts from here but in every case I end up receiving the following exception during the build.

Have anyone successfully used MapStruct together with Lombok under Quarkus? Any help is appreciated.

Strangely the first compile after a mvn clean always succeeds and the second compile or running the application throws this:

Error:(9,8) java: Internal error in the mapping processor: java.lang.RuntimeException:
javax.annotation.processing.FilerException: Attempt to recreate a file for type com.example.service.RawContentDtoMapperImpl
at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.createSourceFile(MapperRenderingProcessor.java:59)
at org.mapstruct.ap.internal.processor.MapperRenderingProcessor.writeToSourceFile(MapperRenderingProcessor.java:39)
...

Mapper config:

@MapperConfig(componentModel = "cdi")
    public interface QuarkusMappingConfig {
}

Mapper:

@Mapper(config = QuarkusMappingConfig.class, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface RawContentDtoMapper { 

    RawContentDTO toResource(RawContent rawContent);

}

With the pom.xml I have tried several different approaches from all the guides I've found for MapStruct+Quarkus and MapStruct+Lombok arrangements. Including the relevant sections from the two main approach:

Shared properties

<properties>
        <compiler-plugin.version>3.8.1</compiler-plugin.version>
        <maven.compiler.parameters>true</maven.compiler.parameters>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
       ...
        <org.mapstruct.version>1.4.0.Beta3</org.mapstruct.version>
        <org.projectlombok.version>1.18.12</org.projectlombok.version>
</properties>

1. Using plugin annotationProcessorPaths

<dependencies>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
        </dependency>
</dependencies>

<build>
       <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <source>${maven.compiler.source}</source>
                        <target>${maven.compiler.target}</target>
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.mapstruct</groupId>
                                <artifactId>mapstruct-processor</artifactId>
                                <version>${org.mapstruct.version}</version>
                            </path>
                            <path>
                                <groupId>org.projectlombok</groupId>
                                <artifactId>lombok</artifactId>
                                <version>${org.projectlombok.version}</version>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
</build>

2. Using mapstruct-processor depencency approach (with and without the maven-compiler-plugin from approach #1. and also with and withouth the annotationProcessorPaths)

<dependencies>        
       <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
            <scope>provided</scope>
        </dependency>
</dependencies>
Swore answered 27/8, 2020 at 16:30 Comment(3)
Did you use the quarkus hot deploy? I remember having some problems there as well. Does a (regular) ' maven clean instal' l and then run quarkus give problems as well?Lumumba
The general problem is that Lombok creates new stuff while processing annotations in existing classes. That's not allowed according JSR269. The problem MapStruct faces is to wait until lombok is finished. MapStruct created an integration point for that (SPI) that Lombok is supposed to call. checkout: github.com/mapstruct/mapstruct/blob/master/processor/src/main/…Lumumba
I've just had the same issue. Not 100% sure if it was this that fixed it but in my POM I changed the order of the annotation processors under the build plugins section so that Lombok was before Mapstruct. It worked after that, strangely.Reveille
M
2

thanks @jste89. I juste invert annotation processor to make it works

  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${compiler-plugin.version}</version>
    <configuration>
      <annotationProcessorPaths>
        <path>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.80</version>
        </path>

        <path>
          <groupId>org.mapstruct</groupId>
          <artifactId>mapstruct-processor</artifactId>
          <version>1.4.2.Final</version>
        </path>
      </annotationProcessorPaths>
    </configuration>
  </plugin>
Mismatch answered 17/5, 2021 at 17:45 Comment(0)
H
6

In our case it was not related to Quarkus but to

    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>${build-helper-maven-plugin.version}</version>
    <executions>
        <execution>
            <id>add-generated-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${generated-sources-path}/wsdl</source>
                </sources>
            </configuration>
        </execution>
    </executions>
</plugin>

The problem was that our add-source sourcefolder was adding the generated sources AND the mapstruct implementation to the source path. Then the mapstruct-processor would try to register the mapstruct sources again, which then would lead to clashes.

Solution: I had to be more specific with the add-sources folderpath and exclude the folder, where mapstruct puts the generated Java classes.

Hummocky answered 23/11, 2020 at 16:26 Comment(2)
This was the most valuable/meaningful answer after a lot of hit & try AND looking for answers. About the ordering of the paths in the annotationProcessorPaths, even that didn't work for me.Semiaquatic
@Semiaquatic What has worked for you?Canikin
M
2

thanks @jste89. I juste invert annotation processor to make it works

  <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>${compiler-plugin.version}</version>
    <configuration>
      <annotationProcessorPaths>
        <path>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.80</version>
        </path>

        <path>
          <groupId>org.mapstruct</groupId>
          <artifactId>mapstruct-processor</artifactId>
          <version>1.4.2.Final</version>
        </path>
      </annotationProcessorPaths>
    </configuration>
  </plugin>
Mismatch answered 17/5, 2021 at 17:45 Comment(0)
D
0

@the_quail is right I had similar issue when I added org.codehaus.mojo for autogenerate stubs form soap ws url.

so I changed the path for generate-sources

${project.build.directory}/generated-sources

${project.build.directory}/generated-sources/wsdl

Darcie answered 26/11, 2021 at 8:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.