Using MapStruct together with Lombok under Quarkus

7.2k views Asked by At

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>
3

There are 3 answers

0
JFouad On BEST ANSWER

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>
0
Minakshi Jha On

@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

2
the_quail On

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.