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

[BUG] Mapstruct mappers are wrong if lombok needs to create Builders in later rounds #3116

Closed
fraenkelc opened this issue Feb 18, 2022 · 6 comments
Assignees
Labels
accepted The issue/enhancement is valid, sensible, and explained in sufficient detail bug
Milestone

Comments

@fraenkelc
Copy link

Describe the bug
the lombok implementation of AstModifyingAnnotationProcessor in

private static boolean isLombokInvoked() {
if (lombokInvoked != null) {
try {
return lombokInvoked.getBoolean(null);
} catch (Exception e) {}
return true;
}
try {
Class<?> data = Class.forName("lombok.launch.AnnotationProcessorHider$AstModificationNotifierData");
lombokInvoked = data.getField("lombokInvoked");
return lombokInvoked.getBoolean(null);
} catch (Exception e) {}
return true;
}
does not work correctly when lombok gets called in a subsequent round to modify a file emitted by a different AP in an earlier round (that contains @SuperBuilder or @Builder).

Instead of reporting to mapstruct if a given type is "complete" lombok reports "complete" for all files as long as it has run once.

To Reproduce
I've uploaded a reproducer project at /~https://github.com/fraenkelc/bug-lombok-mapstruct-ap

Steps:

  1. create an AP that writes a source file which contains the @SuperBuilder (probably also affects @Builder) lombok annotation
  2. Use this AP together with Lombok, mapstruct and the lombok-mapstruct binding in a project
  3. Write a Mapper that maps to the generated file
  4. compile
  5. Mapstruct will run too early and not see the modified ast and in turn not use the lomboks builder
    /~https://github.com/fraenkelc/bug-lombok-mapstruct-ap/blob/aa68ee421703115af6cd7c19d1045d3e110d506c/README.md?plain=1#L21-L43

Expected behavior
Lombok should correctly delay Mapstruct until it is done, e.g. by implementing AstModifyingAnnotationProcessor with a per-type logic instead of the current "ran once and done" logic.

Version info (please complete the following information):

  • 1.18.22
  • Java 11.0.14.1 (Eclipse Adoptium)
@fraenkelc fraenkelc changed the title [BUG] Mapstruct mappers are wrong if lombok changes code in later rounds [BUG] Mapstruct mappers are wrong if lombok needs to create Builders in later rounds Feb 18, 2022
@Drevsh
Copy link

Drevsh commented Mar 8, 2022

I think I'm running into that issue as well.

I have a DTO class which uses @Builder. When I try to map to this DTO I get the following error message from mapstrcut:

Unknown property "addOns" in result type Item.ItemBuilder. Did you mean "null"?

Interesting enough I only get the issue with Collections but everything else works fine.

The DTO looks as follows:

@Builder
@Getter
@Setter 
@NoArgsConstructor  
@AllArgsConstructor  
public class Item {  
	private String comment;  
	private Collection<Long> addOns;  
}

Without the addOns collection mapstruct uses the builder, but ignores the collection.

ItemBuilder item1 = Item.builder();
item1.comment( item.getComment() );
// some more mappings, but addOns is missing

As soon as I also want the collection mapped I get an error.

@Rawi01 Rawi01 self-assigned this Mar 11, 2022
@Rawi01 Rawi01 added bug accepted The issue/enhancement is valid, sensible, and explained in sufficient detail labels Mar 11, 2022
@Rawi01
Copy link
Collaborator

Rawi01 commented Mar 11, 2022

@Drevsh Do you use an additional annotation processor to generate a new class with lombok annotations and try to map this one using mapstruct? If not your problem is something different. You can try if it is a lombok problem by replacing the lombok version with a delomboked version of your class.

@fraenkelc Thanks for providing the example project. I tried to fix this by adding all processed classes to a Set and let the binding check if it contains the TypeMirror. This doesn't work as expected because MapStruct also calls this method for unprocessed types e.g. java.util.ArrayList. I think we can somehow solve this but it might take some time.

@oenie
Copy link

oenie commented Jul 18, 2022

@Rawi01 Have you tried (if that's possible) to turn off the useBuilder feature in your mapstruct ?

@Mapper(componentModel = "cdi", builder = @builder(disableBuilder = true))

@jakabgyonci97
Copy link

jakabgyonci97 commented Aug 4, 2023

I think I'm running into that issue as well.

I have a DTO class which uses @Builder. When I try to map to this DTO I get the following error message from mapstrcut:

Unknown property "addOns" in result type Item.ItemBuilder. Did you mean "null"?

Interesting enough I only get the issue with Collections but everything else works fine.

The DTO looks as follows:

@Builder
@Getter
@Setter 
@NoArgsConstructor  
@AllArgsConstructor  
public class Item {  
	private String comment;  
	private Collection<Long> addOns;  
}

Without the addOns collection mapstruct uses the builder, but ignores the collection.

ItemBuilder item1 = Item.builder();
item1.comment( item.getComment() );
// some more mappings, but addOns is missing

As soon as I also want the collection mapped I get an error.

Strange enough, I had a similar issue. In my case the addOn property was a simple String. Would it be possible that the problem is the property name? Like addOn being a special word?

@rzwitserloot
Copy link
Collaborator

Gracias to @kanchev1 for fixing this one! Will be in next lombok release.

@rzwitserloot
Copy link
Collaborator

... oof, have to pull the rug on this one. @kanchev1's fix is getting reverted now and is as far as we can tell fundamentally the wrong approach. Comments as to why kanchev's approach appears to be a dead end will be posted as comments on the PR, which is #3744 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted The issue/enhancement is valid, sensible, and explained in sufficient detail bug
Projects
None yet
Development

No branches or pull requests

6 participants