Skip to content

StackOverflowError in MapStruct during annotation processing when resolving generics where target's field type and user-defined mapping target type implement the same self-referential generic #3948

@ArR4e

Description

@ArR4e

Expected behavior

Compilation and annotation processing succeed

Actual behavior

Instead, annotation processing blows up due to StackOverflowError, and compilation fails.
It happens when:

  1. Mapper's target has a field that is of a type that implements self-referential generic
  2. 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:

  1. 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
  2. visitDeclared is called where parameterized is type A, declared is type B
  3. we check B's directSuperTypes, which includes Comparable
  4. visitDeclared is called on A and Comparable, we reach a branch where we check A's superTypes (includes Comparable)
  5. visitedDeclared is called on Comparable and Comparable, we reach branch that checks that generic types are the same and tries to match type arguments
  6. 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions