1

I am working with code that uses a library i can not change with a method annotated @NotNull (org.jetbrains), that does return null regardless of the annotation. Here is a simplified example:

@NotNull
public Company getCompany(CompanyKey companyKey) {
  Company company = em.find(Company.class, companyKey.getKey());
  if (company != null) {
    return company
  } else {
    return null;
  }
}

To account for getCompany returning null, the original developer thought he has to check the return value.

Now, reading the docs for @NotNull i see that it says that a NotNull-annotated method will throw an IllegalStateException when it does return null. But i assume that this is only true if the code was compiled in the IDE, because i read somewhere that the Jetbrains compiler inserts this behavior. And production code is usually (and so in this case) not compiled in the IDE.

The null check is no problem to me, but for this code:

Company company = companyService.getCompany(companyKey);
if (company != null) { // <- this is the offending line
  // do the intended thing, real code omitted
} else {
  log.warning("warning message");
}

i get a warning in the IDE (annoying, but no great problem) and Sonarqube reports this as a bug, because it says that handle it... is dead code, which is "always buggy and should never be used in production". Now, this is even more annoying and even a real problem, because it reduces the Reliability rating and the code fails to pass the quality gate.

I tried annotating the code like this

@SuppressWarnings("java:S2583") // <- this is the aforementioned Sonarlint rule
Company company = companyService.getCompany(companyKey);

but this does not work because the offending null check is in the following line and the annotation has to be placed on the variable declaration.

I also tried

@Nullable
Company company = companyService.getCompany(companyKey);

which does not have any effect.

I know i could annotate the whole method with @SuppressWarnings("java:S2583"), but i would like to avoid that and would like to know if there is a better solution.

Pao
  • 843
  • 5
  • 17
  • I'm wondering how the initial code *ever* passed a review, but we probably know that answer to that one... – filpa Jun 21 '23 at 13:51
  • It's just the Sonaqube error which is annoying right ? Just add some : log.debug("problem comes from library"); in that if statement, and problem solved, no ? – Pras Jun 21 '23 at 13:55
  • @Pras: That's what the "handle it" "code" currently consists of. Annoying me or others is not the problem, passing the quality gate is the problem. And because Sonarqube classifies this as bug, the Reliability rating is reduced, currently to C, where B is required. I will edit the question to clarify that it might not be a problem, but in fact really is a problem. – Pao Jun 21 '23 at 14:02
  • Hmm, what i am saying is that "handle it" is no code, just a comment. "log.debug" is code, and sonarqube will no longer classify this as a bug – Pras Jun 21 '23 at 14:35
  • Well, in fact the real code is slightly different and i simplified to the version in the question and omitted the log. I will edit the question to clarify this. – Pao Jun 21 '23 at 14:36
  • The comment " [...] log.debug is code, and sonarqube will no longer classify this is a bug" set me thinking. So i commented out the log line to see if code or comment in this place makes a difference, but Sonarlint still complains about the `company != null` condition, so i think that Sonarqube will also keep seeing this as a bug. – Pao Jun 21 '23 at 14:54
  • yes ok, the complain is on the if statement, and not on the comment as i thought. Sorry, i misunderstood – Pras Jun 21 '23 at 15:20

2 Answers2

0

Did you try with Optional like this: Optional<Company> company = Optional.ofNullable(companyService.getCompany(companyKey)); ? after your check will be company.isPresent()

Andrei Lisa
  • 1,361
  • 3
  • 11
  • Sonarlint still thinks that the Optional can only be non null and reports the same error. – Pao Jun 21 '23 at 14:34
  • Did it help you ? [link](https://stackoverflow.com/questions/66310483/how-to-handle-sonarlint-javas2259-null-pointers-should-not-be-dereferenced) or [link](https://stackoverflow.com/questions/34848491/false-positive-in-sonarqube-squids2583) – Andrei Lisa Jun 21 '23 at 14:38
  • No, sorry, the first link is about the opposite, i think, where null can occur without being handled. The second link is about a false positive and sonar bug. In my case Sonar cannot see the underlying code and relies on the annotation to be correct, which is kind of a false positive, but not Sonar's failure. – Pao Jun 21 '23 at 14:46
  • So, it is ok in my opinion to suppress warnings if you are absolutely sure what you are doing and it would be better to document such things for future changes (e.g. java doc or comments) – Andrei Lisa Jun 21 '23 at 14:56
  • Yes, correct, i would just like to avoid suppressing warnings for the whole method, which does a few things more. – Pao Jun 21 '23 at 15:00
  • I am sure you can extract part of this code to another method and just call where you need it. But how i think that is an good approach and how i do(not permanently) every method is responsible for just one thing. – Andrei Lisa Jun 21 '23 at 15:17
0

For the IDE warning if it is IntelliJ you could add:

//noinspection ConstantConditions
3AKOBAH
  • 105
  • 6