Skip to content

Cannot map from a covariant (extends) generic type #2677

@HawkSK

Description

@HawkSK
  • Is this an issue (and hence not a question)?

I am trying to use a covariant generic type (<? extends X>) in the mapping parameter and the result is

Internal error in the mapping processor: java.lang.NullPointerException  
at org.mapstruct.ap.internal.util.workarounds.SpecificCompilerWorkarounds.replaceTypeElementIfNecessary(SpecificCompilerWorkarounds.java:99)  
at org.mapstruct.ap.internal.util.Executables.getAllEnclosedExecutableElements(Executables.java:98)  
at org.mapstruct.ap.internal.model.common.Type.getAllMethods(Type.java:665)  
at org.mapstruct.ap.internal.model.common.Type.getPropertyReadAccessors(Type.java:517)  
at org.mapstruct.ap.internal.model.beanmapping.SourceReference.push(SourceReference.java:423)  
at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.applyTargetThisMapping(BeanMappingMethod.java:1207)  
at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.build(BeanMappingMethod.java:268)  
at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMappingMethods(MapperCreationProcessor.java:378)  
at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMapper(MapperCreationProcessor.java:152)  
at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:123)  
at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:74)  
at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:338)  
at org.mapstruct.ap.MappingProcessor.processMapperTypeElement(MappingProcessor.java:318)  
at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:267)  
at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:166)  
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:980)  
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:896)  
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1222)  
at jdk.compiler/com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1334)  
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1258)  
at jdk.compiler/com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:936)  
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0(JavacTaskImpl.java:104)  
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.handleExceptions(JavacTaskImpl.java:147)  
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:100)  
at jdk.compiler/com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:94)  
at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:126)  
at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:174)  
at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:1134)  
at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:187)  
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)  
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)  
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)  
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call(MultiThreadedBuilder.java:190)  
at org.apache.maven.lifecycle.internal.builder.multithreaded.MultiThreadedBuilder$1.call(MultiThreadedBuilder.java:186)  
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)  
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)  
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)  
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)  
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)  
at java.base/java.lang.Thread.run(Thread.java:834)

The simplified code that produces this is:

@Mapper
public interface GenericMapper {
    @Mapping(target = ".", source = "value")
    Output map(Wrapper<? extends Parent> in); // Internal error in the mapping processor

    @Mapping(target = ".", source = "value")
    Output mapFromParent(Wrapper<Parent> in); // works

    @Mapping(target = ".", source = "value")
    Output mapFromChild(Wrapper<Child> in); // works
}

with classes

class Wrapper<T> {
    private boolean status;
    private T value;

    public void setStatus(boolean status) { this.status = status; }
    public void setValue(T value) { this.value = value; }
    public boolean isStatus() { return status;}
    public T getValue() { return value; }
}

class Parent {
    private int id;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
}

class Child extends Parent {
    private String whatever;

    public String getWhatever() { return whatever; }
    public void setWhatever(String whatever) { this.whatever = whatever; }
}

class Output {
    int id;
    boolean status;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public boolean isStatus() { return status; }
    public void setStatus(boolean status) { this.status = status; }
}

Mapstruct: 1.4.2.Final
JDK: Amazon Coretto 11.0.4
Maven: 3.6.3
IntelliJ Idea: 2021.2.3 Ultimate

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions