使用MapStruct和Lombok在Quarkus下。

huangapple go评论151阅读模式
英文:

Using MapStruct together with Lombok under Quarkus

问题

我正在按照 MapStruct 博客上的指南进行操作,但在将这三种技术一起使用时遇到了问题。
我已经尝试了 MapStruct 文档、错误报告、以及这里的帖子中提到的几种方法,但在每种情况下,我最终都会在构建过程中收到以下异常信息

是否有人成功地将 MapStruct 与 Lombok 在 Quarkus 下一起使用过?非常感谢任何帮助。

奇怪的是,mvn clean 后的第一次 compile 总是成功的,而第二次 compile 或运行应用程序时会抛出以下错误:

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)
...

映射器配置:

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

映射器:

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

    RawContentDTO toResource(RawContent rawContent);

}

在 pom.xml 中,我尝试了几种不同的方法,包括所有我找到的关于 MapStruct+Quarkus 和 MapStruct+Lombok 结合的指南中的相关部分。包括两种主要方法的相关部分:

共享属性

<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. 使用插件 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. 使用 mapstruct-processor 依赖方法(包括从方法 #1 中的 maven-compiler-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>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
英文:

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 = &quot;cdi&quot;)
    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

&lt;properties&gt;
        &lt;compiler-plugin.version&gt;3.8.1&lt;/compiler-plugin.version&gt;
        &lt;maven.compiler.parameters&gt;true&lt;/maven.compiler.parameters&gt;
        &lt;maven.compiler.source&gt;11&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;11&lt;/maven.compiler.target&gt;
       ...
        &lt;org.mapstruct.version&gt;1.4.0.Beta3&lt;/org.mapstruct.version&gt;
        &lt;org.projectlombok.version&gt;1.18.12&lt;/org.projectlombok.version&gt;
&lt;/properties&gt;

1. Using plugin annotationProcessorPaths

&lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
            &lt;artifactId&gt;mapstruct&lt;/artifactId&gt;
            &lt;version&gt;${org.mapstruct.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
            &lt;artifactId&gt;lombok&lt;/artifactId&gt;
            &lt;version&gt;${org.projectlombok.version}&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
&lt;/dependencies&gt;

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

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

&lt;dependencies&gt;        
       &lt;dependency&gt;
            &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
            &lt;artifactId&gt;mapstruct&lt;/artifactId&gt;
            &lt;version&gt;${org.mapstruct.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
            &lt;artifactId&gt;lombok&lt;/artifactId&gt;
            &lt;version&gt;${org.projectlombok.version}&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
            &lt;artifactId&gt;mapstruct-processor&lt;/artifactId&gt;
            &lt;version&gt;${org.mapstruct.version}&lt;/version&gt;
            &lt;scope&gt;provided&lt;/scope&gt;
        &lt;/dependency&gt;
&lt;/dependencies&gt;

答案1

得分: 5

在我们的情况下,与 Quarkus 无关,而与以下插件相关:

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

问题在于我们的 add-source 源文件夹将生成的源代码和 mapstruct 实现都添加到了源代码路径中。然后,mapstruct-processor 将尝试重新注册 mapstruct 源代码,这会导致冲突。

解决方案:我需要更具体地指定 add-sources 文件夹路径,并排除 mapstruct 放置生成的 Java 类的文件夹。

英文:

In our case it was not related to Quarkus but to

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

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.

答案2

得分: 1

感谢 @jste89。
我只是将注解处理器反转以使其正常工作

maven-compiler-plugin
${compiler-plugin.version}

org.projectlombok
lombok
1.18.80
  <path>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.4.2.Final</version>
  </path>
</annotationProcessorPaths>

英文:

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

  &lt;plugin&gt;
    &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
    &lt;version&gt;${compiler-plugin.version}&lt;/version&gt;
    &lt;configuration&gt;
      &lt;annotationProcessorPaths&gt;
        &lt;path&gt;
          &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;
          &lt;artifactId&gt;lombok&lt;/artifactId&gt;
          &lt;version&gt;1.18.80&lt;/version&gt;
        &lt;/path&gt;

        &lt;path&gt;
          &lt;groupId&gt;org.mapstruct&lt;/groupId&gt;
          &lt;artifactId&gt;mapstruct-processor&lt;/artifactId&gt;
          &lt;version&gt;1.4.2.Final&lt;/version&gt;
        &lt;/path&gt;
      &lt;/annotationProcessorPaths&gt;
    &lt;/configuration&gt;
  &lt;/plugin&gt;

答案3

得分: 0

@the_quail 是正确的,当我添加了 org.codehaus.mojo 以便从 SOAP Web 服务 URL 自动生成存根时,我遇到了类似的问题。

所以我将路径更改为:

<phase>generate-sources</phase>

<sourceDestDir>${project.build.directory}/generated-sources</sourceDestDir>

<sourceDestDir>${project.build.directory}/generated-sources/wsdl</sourceDestDir>
英文:

@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 <phase>generate-sources</phase>

<sourceDestDir> ${project.build.directory}/generated-sources </sourceDestDir>

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

huangapple
  • 本文由 发表于 2020年8月28日 00:30:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63620377.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定