Expected behavior
Compilation and annotation processing succeed
Actual behavior
Instead, annotation processing blows up due to StackOverflowError, and compilation fails.
It happens when:
- Mapper's target has a field that is of a type that implements self-referential generic
- There is a user-defined mapping method whose target is another type, that implements same self-referential generic
One such generic is std's Comparable, where implementing class usually looks like class Foo implements Comparable
The problem is in this method that recurses until StackOverflow:
https://github.com/mapstruct/mapstruct/blob/main/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java#L1621
visitDeclared doesn't check that types were already tried to be matched
In above mentioned setup:
- Let's assume that the type of mapper's target field is A, which implements Comparable, there is a user-defined mapping for B, which also implements Comparable
- visitDeclared is called where parameterized is type A, declared is type B
- we check B's directSuperTypes, which includes Comparable
- visitDeclared is called on A and Comparable, we reach a branch where we check A's superTypes (includes Comparable)
- visitedDeclared is called on Comparable and Comparable, we reach branch that checks that generic types are the same and tries to match type arguments
- we are back at comparing A and B types, and recursion continues
Steps to reproduce the problem
Here is a minimal example that fails to compile
map-struct-bug.zip
MapStruct Version
1.5.5(maybe earlier)-1.6.3 (checked latest state of main branch does not seem to be fixed)