vscode-java icon indicating copy to clipboard operation
vscode-java copied to clipboard

Maven multi-module project mapstruct duplicate generation

Open cdisk opened this issue 1 year ago • 9 comments

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
  1. 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]
  1. 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.

cdisk avatar Jun 05 '24 06:06 cdisk

same issue

qzwzqty avatar Mar 07 '25 08:03 qzwzqty

@qzwzqty Could you attach a project example reproducing the error?

snjeza avatar Mar 07 '25 16:03 snjeza

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

Image

qzwzqty avatar Mar 09 '25 09:03 qzwzqty

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

snjeza avatar Mar 11 '25 15:03 snjeza

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

linpeilie avatar Mar 12 '25 02:03 linpeilie

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?

snjeza avatar Mar 12 '25 03:03 snjeza

Because I want to force this annotation handler to execute, and there is no feedback from eclipse that this is an issue.

linpeilie avatar Mar 12 '25 04:03 linpeilie

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?

snjeza avatar Mar 12 '25 16:03 snjeza

ok, i'll try your suggestion.

linpeilie avatar Mar 13 '25 02:03 linpeilie