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

Provide an extension for MapStruct #5956

Open
gunnarmorling opened this issue Dec 5, 2019 · 12 comments
Open

Provide an extension for MapStruct #5956

gunnarmorling opened this issue Dec 5, 2019 · 12 comments
Labels
kind/extension-proposal Discuss and Propose new extensions

Comments

@gunnarmorling
Copy link
Contributor

Describe the extension

MapStruct is a compile-time code generator (JSR 269 annotation processor) for bean-to-bean-mappings, useful e.g. to map an internal (entity) model to the external (REST) model of an application. As the generated code avoids any kind of reflection, MapStruct leans itself to being a perfect match with Quarkus and GraalVM.

Interested in this extension, please +1 via the emoji/reaction feature of GitHub (top right).

Configuration suggestion

MapStruct has a few annotation processor options that impact the generated source code (e.g. whether to include or not a timestamp). I suppose they might be made static Quarkus properties, but not sure whether that's needed really. To clarify, these options are not examined by the generated code, but they impact how the code is generated.

Additional context

MapStruct works with Quarkus/GraalVM out-of-the-box. So the value of the extension would be better a getting started experience by means of selecting it from the catalogue. One thing it actually could do is to enable all generated mappers for reflection. That's not needed when using CDI as the component model for the generated code (which is what I'd recommend with Quarkus), but there's an alternative way to obtain mapper instances which uses reflection (Mappers.getInstance(MyMapper.class)). This is the only location where reflection is used so it'd benefit from automatic enabling this.

@gunnarmorling gunnarmorling added the kind/extension-proposal Discuss and Propose new extensions label Dec 5, 2019
@gunnarmorling
Copy link
Contributor Author

Hey @chris922, together with @gsmet and @Sanne we were discussing to have an official Quarkus extension for MapStruct. As you nicely point out in your post, MapStruct really works out of the box here, but such extension would still make for a nicer getting started experience and people could choose it from the extension catalogue etc. Would you perhaps be interested in leading this effort?

@gunnarmorling
Copy link
Contributor Author

Btw. a related yet general question is: how should annotation processors such as MapStruct or the JPA metamodel generator integrated into Quarkus? I was thinking whether it'd make sense to have a JSR 269 Filer implementation which takes the generated source code and builds byte code right away. Just thinking out loud, perhaps it doesn't add value.

@Sanne
Copy link
Member

Sanne commented Dec 5, 2019

@gunnarmorling we don't dislike annotation-processors; as you pointed out during one of the brainstorming meetings, while their API is a hard nut they provide nice integration with the IDEs, allowing auto-completion to work on the fly: seems fitting for MapStruct and JPA metamodel.

I think we should keep that - unless I misunderstood what you have in mind?

@gunnarmorling
Copy link
Contributor Author

gunnarmorling commented Dec 5, 2019

I think we should keep that

Ok, cool. I somehow had the impression that you'd want to move away from annotation processors, but it's good to know that this isn't the case.

Btw. a related issue in this context is #1502, which prevents APs from being re-run after code changes during Dev mode in certain set-ups. Would be nice to have this addressed, as currently the set-up we recommend (using the annotationProcessPaths option of the Maven compiler plug-in) isn't working with Dev mode, so the AP JAR must be added as a dependency instead which isn't ideal.

@Sanne
Copy link
Member

Sanne commented Dec 5, 2019

Ok, cool. I somehow had the impression that you'd want to move away from annotation processors, but it's good to know that this isn't the case.

Following your advice :)

Regarding #1502 I don't know, need to leave that to others. Sad to see it's rather old and yet unaddressed.

lhenriquegomescamilo added a commit to lhenriquegomescamilo/my-ifood that referenced this issue Oct 12, 2020
… the quarkus not provides an extension or processor notation to kotlin and mapstruct:

* quarkusio/quarkus#5956
* quarkusio/quarkus#11215
@maxandersen
Copy link
Member

annotation processors are generally slow compared to a more direct quarkus extension so if we can avoid them it would be great.

another issue I keep having with mapstruct is that it requires my fields to be public where we don't need elsewhere. could a proper mapstruct extension remedy that ?

@filiphr
Copy link

filiphr commented Sep 23, 2021

annotation processors are generally slow compared to a more direct quarkus extension so if we can avoid them it would be great.

I am not entirely sure how Quarkus extensions works. However, shouldn't the annotation processor eventually be involved somehow? How would the generated code be invoked otherwise?

another issue I keep having with mapstruct is that it requires my fields to be public where we don't need elsewhere. could a proper mapstruct extension remedy that ?

I would be curious to understand why you think that mapstruct needs the fields to be public. MapStruct does not have such a requirement. You need to have public getters / setters. There is mapstruct/mapstruct#1689 which asks for having the ability to use non public visibility. If that's what you are looking for, I do not think that a Quarkus extension will help, since it is something that we explicitly check for in the MapStruct annotation processor.

@Sanne
Copy link
Member

Sanne commented Sep 23, 2021

annotation processors are generally slow compared to a more direct quarkus extension so if we can avoid them it would be great.

There are some situations in which we prefer an AP for code generation: the cases in which it's useful to have immediate feedback within the IDE.

I believe this is one of such cases so it might be worth sticking to the AP approach.

@maxandersen
Copy link
Member

@filiphr I'm talking about fields, especially package private scoped not needing public accessors. Yes I seen the #1689 from 2019 thus I assumed there were some technical reason (like having to use reflection in the generated source) for why it wasn't there.

Hence I just wondered if the mapping implementations were code generated during build (rather than in compile phase) mapstruct could do more.

@Sanne maybe i'm missing some feature of mapstruct but how is this different from i.e. hibernate validating errors at build time ? with quarkus:dev you get errors too while coding.

@filiphr
Copy link

filiphr commented Sep 24, 2021

Yes I seen the mapstruct/mapstruct#1689 from 2019 thus I assumed there were some technical reason (like having to use reflection in the generated source) for why it wasn't there.

It is more of a maintenance thing from our side, we need to do some refactorings to make sure we have access to package that the class will be generated to be able to determine whether we can do the mapping or not. It has nothing to do with reflection since MapStruct uses no reflection to do the mapping.

@maxandersen
Copy link
Member

I believe this is one of such cases so it might be worth sticking to the AP approach.

https://quarkusio.zulipchat.com/#narrow/stream/187030-users/topic/.E2.9C.94.20Mapstruct.20mapper.20implementation.20generation/near/256740166

"I'm using MapStruct.
I've followed that guide: https://mapstruct.org/news/2019-12-06-mapstruct-and-quarkus/

I'm currently annoyed because I'm getting comfortable using quarkus:dev mode and mapstruct processor does'nt "regenerate" on the fly the modification made to the mapper.

I need to kill the current running application and mvn compile quarkus:dev.

By specifying the compile phase the mapstruct processor will generate implementation of the mapper. Is there's a way to force that while being in quarkus:dev mode?"

just a reference that things could be better.

@geoand
Copy link
Contributor

geoand commented Feb 26, 2024

I'm currently annoyed because I'm getting comfortable using quarkus:dev mode and mapstruct processor does'nt "regenerate" on the fly the modification made to the mapper.

Is this still the case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/extension-proposal Discuss and Propose new extensions
Projects
None yet
Development

No branches or pull requests

5 participants