Maven multi-module project mapstruct duplicate generation
Environment
- Operating System: Windows 10 22H2
- JDK version: openjdk 21.0.2
- Visual Studio Code version: 1.89.1
- Java extension version: v1.32.2024053108 (pre-release)
Steps To Reproduce
- Create a Maven multi-module project with the following structure: ruoyi-parent
- ruoyi-admin
-
- dependency: ruoyi-modeles/ruoyi-demo
-
- dependency: ruoyi-modeles/ruoyi-system
- ruoyi-modeles
-
- ruoyi-demo
-
-
- [mapper auto-generation here]
-
-
- ruoyi-system
-
-
- [mapper auto-generation here]
-
- Build the project.
Internal error in the mapping processor: java.lang.RuntimeException: javax.annotation.processing.FilerException:
Source file already created: /ruoyi-admin/target/generated-sources/annotations/com/ruoyi/system/domain/vo/SysTenantVoToTenantListVoMapperImpl.java at
org.mapstruct.ap.internal.processor.MapperRenderingProcessor.createSourceFile(MapperRenderingProcessor.java:59) at
org.mapstruct.ap.internal.processor.MapperRenderingProcessor.writeToSourceFile(MapperRenderingProcessor.java:39) at
org.mapstruct.ap.internal.processor.MapperRenderingProcessor.process(MapperRenderingProcessor.java:29) at
org.mapstruct.ap.internal.processor.MapperRenderingProcessor.process(MapperRenderingProcessor.java:24) at
org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:350) at
org.mapstruct.ap.MappingProcessor.processMapperTypeElement(MappingProcessor.java:330) at
org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:279) at
org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:174) at
org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:141) at
org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.round(RoundDispatcher.java:112) at
org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager.processAnnotations(BaseAnnotationProcessorManager.java:172) at
org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager.processAnnotations(IdeAnnotationProcessorManager.java:134) at org.eclipse.jdt.internal.compiler.Compiler.processAnnotations(Compiler.java:952) at
org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:449) at
org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:468) at
org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:425) at
org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:410) at
org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:211) at
org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:341) at
org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:79) at
org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:286) at
org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:192) at
org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1077) at
org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47) at
org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:296) at
org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:352) at
org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:441) at
org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:47) at
org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:444) at
org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:555) at
org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:503) at
org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:585) at
org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:207) at
org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:300) at
org.eclipse.core.internal.jobs.Worker.run(Worker.java:63) Caused by: javax.annotation.processing.FilerException: Source file already created: /ruoyi-admin/target/generated-sources/annotations/com/ruoyi/system/domain/vo/SysTenantVoToTenantListVoMapperImpl.java at
org.eclipse.jdt.internal.apt.pluggable.core.filer.IdeFilerImpl.createSourceFile(IdeFilerImpl.java:161) at
org.mapstruct.ap.internal.processor.MapperRenderingProcessor.createSourceFile(MapperRenderingProcessor.java:56) ... 34 more
Current Result
The mapper files are automatically generated in the generated-sources directory of both the parent and child modules.
Expected Result
The mapper files should be generated only in the respective module's generated-sources directory where the mappers are defined.
same issue
@qzwzqty Could you attach a project example reproducing the error?
@snjeza https://github.com/dromara/RuoYi-Cloud-Plus This project can be replicated. My project is based on this one. Below is one of the screenshots showing the error.
This issue is related to MapStruct Plus
The project declares the org.mapstruct.ap.MappingProcessor annotation processor. See https://github.com/linpeilie/mapstruct-plus/blob/main/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
The processor is already declared in mapstruct. See https://github.com/mapstruct/mapstruct/blob/main/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
Because of that, Eclipse jdt.core runs org.mapstruct.ap.MappingProcessor twice.
The solutions:
-
MapStruct Plus wouldn't need to declare
org.mapstruct.ap.MappingProcessor. - Eclipse jdt.core should check if an annotation processor defined more times
This looks a lot like using Eclipse jdt.core by default to run Java projects. The compiled code is already generated by building the project first, but running the project seems to generate the code again. However, using Java commands to execute projects or ideas to execute projects does not present this problem
This looks a lot like using Eclipse jdt.core by default to run Java projects.
Right.
VS Code uses Eclipse jdt.core to build/compile Java projects.
This issue can also be reproduced in Eclipse.
@linpeilie Why did you add org.mapstruct.ap.MappingProcessor at https://github.com/linpeilie/mapstruct-plus/blob/main/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor? It is already added by org.mapstruct:mapstruct-processor.
If you delete it, mvn clean verify -DskipTests, VS Code and Eclipse work correctly.
A potential patch
diff --git a/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
index 78ca476..db54bed 100644
--- a/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
+++ b/mapstruct-plus-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -1,2 +1 @@
io.github.linpeilie.processor.AutoMapperProcessor
-org.mapstruct.ap.MappingProcessor
\ No newline at end of file
@rgrunber What do you think about fixing this issue in Eclipse jdt.core?
Because I want to force this annotation handler to execute, and there is no feedback from eclipse that this is an issue.
Because I want to force this annotation handler to execute, and there is no feedback from eclipse that this is an issue.
This is unnecessary because your project includes org.mapstruct:mapstruct-processor.
Eclipse doesn't throw an error because it finds org.mapstruct.ap.MappingProcessor and executes it twice.
org.mapstruct.ap.MappingProcessor throws an error when executed multiple times.
Can you try the patch I added in the previous comment?
ok, i'll try your suggestion.