False positive on S1206

SonarQube 8.9.1 + maven sonar plugin 3.9.0.2155

package com.example;

public class DestinatarioEmail {
  private String mailTo;
  
  private String mailCc;
  
  private String mailBcc;
  
  private DestinatarioEmail(){
  }

  public DestinatarioEmail(String mailTo) {
    super();
    this.mailTo = mailTo;
  }

  public DestinatarioEmail(String mailTo, String mailCc, String mailBcc) {
    super();
    this.mailTo = mailTo;
    this.mailCc = mailCc;
    this.mailBcc = mailBcc;
  }

  public String getMailTo() {
    return mailTo;
  }

  public String getMailCc() {
    return mailCc;
  }

  public String getMailBcc() {
    return mailBcc;
  }

  public void setMailCc(String mailCc) {
    this.mailCc = mailCc;
  }

  public void setMailBcc(String mailBcc) {
    this.mailBcc = mailBcc;
  }

  @Override
  public String toString() {
    return "DestinatarioEmail [mailTo=" + mailTo + ", mailCc=" + mailCc + ", mailBcc=" + mailBcc + "]";
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((mailBcc == null) ? 0 : mailBcc.hashCode());
    result = prime * result + ((mailCc == null) ? 0 : mailCc.hashCode());
    result = prime * result + ((mailTo == null) ? 0 : mailTo.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof DestinatarioEmail)) {
      return false;
    }
    DestinatarioEmail other = (DestinatarioEmail) obj;
    if (mailBcc == null) {
      if (other.mailBcc != null) {
        return false;
      }
    } else if (!mailBcc.equals(other.mailBcc)) {
      return false;
    }
    if (mailCc == null) {
      if (other.mailCc != null) {
        return false;
      }
    } else if (!mailCc.equals(other.mailCc)) {
      return false;
    }
    if (mailTo == null) {
      if (other.mailTo != null) {
        return false;
      }
    } else if (!mailTo.equals(other.mailTo)) {
      return false;
    }
    return true;
  }  
}

SonarQube raises S1206 violation (This class overrides “hashCode()” and should therefore also override “equals()”.) also if equals is present.

Hello @michele.lorenzini

The code you provided does not raise a false positive on my side.

I suspect that types can not be resolved correctly. Could you provide the logs of the analysis? I’m mainly looking for something looking like: Unresolved imports/types have been detected during analysis. Enable DEBUG mode to see them.. Ideally, it would be great if you could enable debug mode as well.

In addition, could you provide the analysis properties of your projects?

After some investigation I found that the problem arise when IBM JDK is used to run SonarQube analysis.
Using Oracle JDK does not produce this false positive (the same applies to False positive on S2142 when Thread.currentThread().interrupt(); is called).

In the log for the IBM build there is this warning:

[WARNING] 16:27:54.825 Unresolved imports/types have been detected during analysis. Enable DEBUG mode to see them.
[DEBUG] 16:27:54.825 Unresolved imports/types:
- Implicit super constructor Object() is undefined. Must explicitly invoke another constructor
- Object cannot be resolved to a type
- String cannot be resolved to a type
- System cannot be resolved
- The constructor Object() is undefined
- The method hashCode() of type DestinatarioEmail must override or implement a supertype method
- The method toString() of type DestinatarioEmail must override or implement a supertype method
- The type java.lang.Object cannot be resolved. It is indirectly referenced from required .class files
- The type java.lang.String cannot be resolved. It is indirectly referenced from required .class files
- The type java.lang.Thread cannot be resolved. It is indirectly referenced from required .class files
- Thread cannot be resolved

I will attach the complete log in debug for the two builds.

mvn-sonar_oracle.log (89.2 KB)
mvn-sonar_ibm.log (97.9 KB)

Hey @michele.lorenzini,

Glad to see that your issue is gone.
If you wish to continue using the IBM JDK, you may want to add <path to the IMM JDK>/jre/lib/<amd64>/default/jclSC180/vm.jar to sonar.java.libraries for now
A ticket has been created to provide a long-term solution.

Dorian