Skip to content

java.lang.StackOverflowError when using generics #3945

Description

@pkernevez

Expected behavior

Do the mapping without StackOverflowError

Actual behavior

When we use:

  • an config with : collectionMappingStrategy = TARGET_IMMUTABLE
  • A default mapping implementation with a generic <T extends ITsidType> ShiftId<T> toShiftId(ShiftRawId id){...}

During the mapping a StackOverflowError is throw.

[ERROR] /Users/pke/SCM/Git/Shift/PbMapStruct/src/main/java/net/kernevez/mapstruct/infiniteloop/CustomMapper.java:[12,8] Internal error in the mapping processor: java.lang.StackOverflowError  	
at jdk.compiler/com.sun.tools.javac.code.Types$12.visitClassType(Types.java:2182)  	
at jdk.compiler/com.sun.tools.javac.code.Types$12.visitClassType(Types.java:2168)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)  	
at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4920)  	
at jdk.compiler/com.sun.tools.javac.code.Types.asSuper(Types.java:2165)  	
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1186)  	
at jdk.compiler/com.sun.tools.javac.code.Types$4.visitClassType(Types.java:1107)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1053)  	
at jdk.compiler/com.sun.tools.javac.code.Types$DefaultTypeVisitor.visit(Types.java:4920)  	
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1103)  	
at jdk.compiler/com.sun.tools.javac.code.Types.isSubtype(Types.java:1074)  	
at jdk.compiler/com.sun.tools.javac.model.JavacTypes.isSubtype(JavacTypes.java:101)  
at org.mapstruct.ap.internal.util.AbstractTypeUtilsDecorator.isSubtypeErased(AbstractTypeUtilsDecorator.java:134)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:236)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:226)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:209)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getTypeParameters(TypeFactory.java:524)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:337)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:226)  	
at org.mapstruct.ap.internal.model.common.TypeFactory.getType(TypeFactory.java:209)  	
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:215)  	
at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(AbstractList.java:722)  	
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570)  	
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560)  	
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)  	
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265)  	
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:727)  	
at org.mapstruct.ap.internal.model.common.Type.getDirectSuperTypes(Type.java:1362)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1625)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:91)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1617)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1639)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1629)  	
at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1532)  	
at jdk.compiler/com.sun.tools.javac.code.Type$ClassType.accept(Type.java:1218)  	
at java.compiler@23.0.1/javax.lang.model.util.AbstractTypeVisitor6.visit(Abst
....

Steps to reproduce the problem

The simpler solution is to use this repo https://github.com/pkernevez/mapstruct-issue I created it to reproduce the issue.

If you try to build it you will have the stacktrace.
You can remove the error by:

// [WARNING] PbMapStruct/target/generated-sources/annotations/net/kernevez/mapstruct/infiniteloop/CustomMapperImpl.java:[27,23] unchecked conversion
    //  required: net.kernevez.mapstruct.infiniteloop.tsid.ShiftId<net.kernevez.mapstruct.infiniteloop.tsid.ITsidType.CalendarType>

The following implementation create the stacktrace during code generation:

    default <T extends ITsidType> ShiftId<T>  toShiftId(ShiftRawId id) {
        return ShiftId.from(id);
    }

The following compilation create the unckeck exception during compilation:

    default ShiftId  toShiftId(ShiftRawId id) {
        return ShiftId.from(id);
    }

The code generated without the generic is exactly the code expected with the generic. We don't expect any change on the generated code.

MapStruct Version

1.6.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions