如何在声纳中解决这个“可能的空指针取消引用”关键问题?

Posted

技术标签:

【中文标题】如何在声纳中解决这个“可能的空指针取消引用”关键问题?【英文标题】:How to fix this "possible null pointer dereference" critical issue in Sonar? 【发布时间】:2022-01-13 09:03:33 【问题描述】:

以下是有问题的方法。

public String getCarById(Integer carId) 
  ResponseEntity<CarString> response = rTempl.getForEntity(url, CarString.class,
        of("car-id", carId.toString()));
  log.debug("code: ", response.getStatusCode());
  return Objects.requireNonNull(response.getBody()).getCarString();

完整的错误如下。

Possible null pointer dereference in <package>.CarRegistryClient.getCarById(Integer) due to return value of called method

Sonar 使用 Objects.requireNonNull() 还不够吗?

更新:向该方法添加了缺失但相关的代码。现在没有代码丢失。

【问题讨论】:

response 可能为空。虽然错误消息令人困惑。 如果 sonar 认为 NPE 是不可避免的(即有一个保证它的代码路径),就会出现该 sonar 错误。你粘贴的代码没有这样的路径;显然,您省略了代码中的某些内容。例如,您省略的代码可能表明response 绝对为空,或者您正在对response 进行空检查,这使得声纳将“响应”识别为可能为空。另外,您的 Objects.requireNonNull 在这里完全没用;去掉它。 (rNN 抛出 NPE;取消引用它,您在此处执行的操作也是如此。您的 rNN 调用没有意义)。 @rzwitserloot:我将缺失但明显相关的代码添加回我的问题中的代码 sn-p。 【参考方案1】:

很可能rTempl.getForEntity 的方法被显式声明为可能返回null,然后您的代码只是取消引用getForEntity 给您的内容而不检查任何内容。您的 requireNonNull 代码检查 response.getBody() 是否返回非空值;它不检查response 本身是否为非空。

而且代码仍然丢失。 rTempl 可能是什么?

【讨论】:

【参考方案2】:

奇怪的是,这就是修复,Sonar 很高兴。

public String getCarById(Integer carId) 
  ResponseEntity<CarString> response = rTempl.getForEntity(url, CarString.class,
        of("car-id", carId.toString()));

  CarString responseBody = response.getBody();
  assert responseBody != null

  log.debug("code: ", response.getStatusCode());
  return response.getBody().getCarString();

我仍然不明白这与我之前通过 Objects.requireNonNull() 的解决方案有何不同。

【讨论】:

以上是关于如何在声纳中解决这个“可能的空指针取消引用”关键问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决声纳错误:无法加载组件类 org.sonar.scanner.scan.ProjectLock

React - 三元运算符和声纳

再次关闭此“FileOutputStream”声纳[重复]

结合声纳的 Jacoco 测试覆盖率

以下声纳问题的解决方案?

将if语句与声纳中的一个括起来