Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.3.0.final. When a mapperImpl uses a builder beforemapping and aftermapping do not appear in the code. #1831

Closed
ghost opened this issue May 24, 2019 · 3 comments

Comments

@ghost
Copy link

ghost commented May 24, 2019

We want to upgrade from 1.2.0.final to 1.3.0.final. We have 33 mappers in total, the generated code is checked into Git. Hence this makes it very easy to check the diff between 1.2.0 and 1.3.0 generated code. We have 5 mappers which use @AfterMapping. Three of them cause unit-tests for the generated mappers to fail. Did some digging and the failing MapperImp files are those which do use our manually created builders. It turns out that in the generated MapperImpl files calls for beforemapping and aftermapping do not exist. They do exist in the generated 1.2.0 files - which can't handle our builders.

I can reproduce the error with a very small mapper for which I've created a github gist. In file TelephoneBuilder I've disabled the build method and the generated code has beforemapping and aftermapping - included in the gist. By enabling the build method and generating code again you will notice that the builder is being used AND the beforemapping and aftermapping do disappear.

I've tried to disable the builders as I've read in the reference guide. We have a multi-project Gradle setup. In the project where the mappers are used I've created the following file: ./src/main/java/META-INF/services/org.mapstruct.ap.spi.BuilderProvider. Contents: org.mapstruct.ap.spi.NoOpBuilderProvider. removed src/main/generatedJava and created the mappers again. No difference, the builders are still being used. Did I place the file in the wrong place......

I've also tried "13.3. Custom Builder Provider" approach. In the generated NoOpBuilderProvider file BuilderProvider and BuilderInfo Eclipse complains with "BuilderProvider cannot be resolved to a type". The build.gradle file for the subproject contains:
ext.libraries = [
//mapstruct_jdk8: "org.mapstruct:mapstruct-jdk8:'1.3.0.Final'", // JDK for 1.2.0.final
mapstruct_jdk8: "org.mapstruct:mapstruct:'1.3.0.Final'",
mapstruct_processor: "org.mapstruct:mapstruct-processor:'1.3.0.Final'",
]
dependencies{
compileOnly libraries.mapstruct_jdk8
annotationProcessor libraries.mapstruct_processor
}. See also mapstruct/mapstruct-examples#66 for our Gradle 5 complete setup.

I hope you can use my example code to figure out what is going on. Perhaps its the way we create our builders or its a shortcoming in mapstruct.

@filiphr
Copy link
Member

filiphr commented May 24, 2019

Thanks for the detailed report @bessels. It really helps to analyse the error.

I think the reason why you have the error is due to #1454 (if builders are used then the @AfterMapping and @BeforeMapping on the type being build won't be called).

One way to solve this would be with the help of the #1811 PR. One other option is the implementation of #1661 and for us to add an annotation processor option to disable builder support.

I think that the reason why your usage of NoOpBuilderProvider is not working is due to the fact that your file is in your sources. However, Gradle puts the processor on the annotationProcessor path which means that the file won't be picked up. You can try to create a different module and put it with scope annotationProcessor and it would work (I think). There are some other similar issues that have the similar problem with Maven.

@ghost
Copy link
Author

ghost commented May 27, 2019

Thanks for the reply and your suggestions.

Decided to upgrade from 1.2.0.final to 1.3.0.final on our develop branch, which has gradle 4.10.2. The setup for this is totally different, a hybrid form of the old and new setup found on your website. No idea why its setup in this way but it works. See this Github gist should you be interested in it.

For Gradle 5 we were forced to use annotationProcessor to get things working. With Gradle 4.10.2 and mapstruct 1.3.0.final I'm getting of course the same failing unit tests. Tried again both methods to disable using the builders, both to no avail. Also getting the same errors wrt NoOpBuilderProvider.

It looks as if something else is in play and not necessarily the annotationProcessor causing the problem (not being able to disable the builders) for us. Very curious if/how others have gotten disabling the builders to work.

The dev team has decided to stay for now with 1.20.final. Almost holiday so will check in a 2-3 weeks to see if any progress has been made and perhaps an RC for 1.4.0 has been released. Hoping the code supplied can help you further.

@thunderhook
Copy link
Contributor

I will close this issue. The author is already deleted, the example code is not reachable, and the issue seems like to have been fixed with #1454. If someone know what the issue was about and is able to reproduce it, we can of cource reopen the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants