publicissapient-france/selma

Null pointer exception with

fennekit opened this issue · 3 comments

Generating a mapper for a generic class with withIoC = IoC.SPRING specified results in an NullPointerException

package it.xctrl.mappers;

import fr.xebia.extras.selma.IoC;
import fr.xebia.extras.selma.Mapper;
import it.xctrl.entity.EntityPageList;
import it.xctrl.entity.MongoEntity;
import it.xctrl.model.PageList;

@Mapper(withIoC = IoC.SPRING, ignoreMissingProperties = true)
public interface PageListMapper<T extends MongoEntity, S> {
  EntityPageList<T> asEntityPageList(PageList<S> source);
  PageList<S> asPageList(EntityPageList<T> source);
}

The mapping for S and T exist.

package it.xctrl.entity;

import org.bson.types.ObjectId;

public interface MongoEntity {

  ObjectId getId();

  void setId(ObjectId id);
}
package it.xctrl.entity;

import java.io.Serializable;
import java.util.Objects;

public class ActionEntity extends ExerciseItemEntity implements Serializable {
  private Integer number = null;

  private String Actionprop = null;

  private String description = null;

  public ActionEntity() {
    super("act");
  }

  public ActionEntity number(Integer number) {
    this.number = number;
    return this;
  }

   /**
   * Get number
   * @return number
  **/
  public Integer getNumber() {
    return number;
  }

  public void setNumber(Integer number) {
    this.number = number;
  }

  public ActionEntity Actionprop(String actionprop) {
    this.Actionprop = actionprop;
    return this;
  }

   /**
   * Get ActionEntityprop
   * @return ActionEntityprop
  **/
  public String getActionprop() {
    return Actionprop;
  }

  public void setActionprop(String actionprop) {
    this.Actionprop = actionprop;
  }


  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    ActionEntity ActionEntity = (ActionEntity) o;
    return Objects.equals(this.number, ActionEntity.number) &&
        Objects.equals(this.Actionprop, ActionEntity.Actionprop) &&
        super.equals(o);
  }

  @Override
  public int hashCode() {
    return Objects.hash(number, Actionprop, super.hashCode());
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }
}
package it.xctrl.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.Objects;

/**
 * Action
 */
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.SpringCodegen", date = "2017-06-24T07:51:53.792Z")

public class Action extends ExerciseItem implements Serializable {
  @JsonProperty("number")
  private Integer number = null;

  @JsonProperty("actionprop")
  private String actionprop = null;

  public Action number(Integer number) {
    this.number = number;
    return this;
  }

   /**
   * Get number
   * @return number
  **/
  public Integer getNumber() {
    return number;
  }

  public void setNumber(Integer number) {
    this.number = number;
  }

  public Action actionprop(String actionprop) {
    this.actionprop = actionprop;
    return this;
  }

   /**
   * Get actionprop
   * @return actionprop
  **/
  public String getActionprop() {
    return actionprop;
  }

  public void setActionprop(String actionprop) {
    this.actionprop = actionprop;
  }


  @Override
  public boolean equals(java.lang.Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    Action action = (Action) o;
    return Objects.equals(this.number, action.number) &&
        Objects.equals(this.actionprop, action.actionprop) &&
        super.equals(o);
  }

  @Override
  public int hashCode() {
    return Objects.hash(number, actionprop, super.hashCode());
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class Action {\n");
    sb.append("    ").append(toIndentedString(super.toString())).append("\n");
    sb.append("    number: ").append(toIndentedString(number)).append("\n");
    sb.append("    actionprop: ").append(toIndentedString(actionprop)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(java.lang.Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project it.xctrl.api: Fatal error compiling: java.lang.NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project it.xctrl.api: Fatal error compiling
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:212)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307)
        at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193)
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106)
        at org.apache.maven.cli.MavenCli.execute(MavenCli.java:863)
        at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
        at org.apache.maven.cli.MavenCli.main(MavenCli.java:199)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: org.apache.maven.plugin.MojoExecutionException: Fatal error compiling
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:796)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.java:129)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:207)
        ... 20 more
Caused by: org.codehaus.plexus.compiler.CompilerException: java.lang.NullPointerException
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:191)
        at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile(JavacCompiler.java:169)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:785)
        ... 23 more
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
        at com.sun.tools.javac.main.Main.compile(Main.java:553)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
        at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess(JavaxToolsCompiler.java:126)
        ... 25 more
Caused by: java.lang.NullPointerException
        at fr.xebia.extras.selma.codegen.MapperClassGenerator.<init>(MapperClassGenerator.java:65)
        at fr.xebia.extras.selma.codegen.MapperProcessor.generateMappingClassses(MapperProcessor.java:86)
        at fr.xebia.extras.selma.codegen.MapperProcessor.process(MapperProcessor.java:71)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
        at com.sun.tools.javac.main.Main.compile(Main.java:523)
        ... 28 more

Hi,

Thanks for reporting this issue.

This does not look to be related to IoC.SPRING.
In PageListMapper<T extends MongoEntity, S>, T and S are generics, which is ok normally. But S will only be recognized as an Object by Selma at compile time. Selma should know the exact type to be mapped at compile time and not at runtime.

There is still a bug, because NPE is not acceptable, but you should define S an T properly.
You can remove @Mapper from the PageListMapper, define an extended interface with the explicit types for T and S, and add the @Mapper to this new interface.

I'll give a look at the NPE to fix it quicky.

Thanks for confirming the issue. Will try your suggestion and will come back to it.

I tried your suggestion and it works like a charm. Thanks