【问题标题】:Is there a way to lint incompatible Java API references with PMD, Checkstyle, SpotBugs, etc?有没有办法用 PMD、Checkstyle、SpotBugs 等对不兼容的 Java API 引用进行 lint?
【发布时间】:2019-06-10 18:28:46
【问题描述】:

我们目前正在使用 Java Compiler 11 并将我们的主要工件部署到 Java 11。这里没有问题。

不幸的是,我们使用的服务仅支持 Java 8,因此我们编译了其中一些以 Java 8 为目标的服务。这里没问题。

我们的问题是开发人员可能会引用 Java 8 在运行时不可用的方法。例如List.of()、Optional::stream等javac版本11会编译成Java 8,但是在JVM版本8上执行会抛出异常。

后者很容易用一个简单的 grep 语句来识别,但后者更复杂,需要理解代码/AST。

我检查了 Checkstyle、Spotbugs 和 PMD 的文档,但没有成功。 IntelliJ 在这方面其实很擅长,但是它不能集成到我们的 CI 管道中。

我们得到了这个幼稚/简单的 grep 语句:

grep --recursive --extended-regexp '[ \(](List|Set|Map).of' 'our_project'

我们希望有一种准确的方法来识别不兼容的 API。

【问题讨论】:

  • 你试过在 IntelliJ 上寻找吗?我知道他们有一些开源项目,也许,只是也许,他们将分析器作为一个独立的库?
  • 另外,我认为有一些 Maven 插件可以解决您的问题,但我不知道它们,必须搜索它们。
  • 最安全的解决方案是尽可能使用 JDK 8 编译 Java 8 代码
  • 也许我在这里误解了这个问题,但你的问题不是简单地解决了by specifying the -source parameter to javac吗?也就是在编译代码的时候指定-source 8还是-source 11?当 Java 编译器完全按照您的要求执行时,为什么要使用 grep 或任何这些实用程序? (即,如果代码使用 Java 8 之后引入的 API 功能,则无法编译在 Java 8 上运行的代码)。所有主要的 IDE 都允许您在构建代码时指定 -source 的值。
  • @skomisa 问题是 -source 8 编译得很好,因为源代码在语法上与 Java 8 兼容。然后,如果您使用 *jdk-8 执行类,它将失败,因为 @987654328 @(例如),不存在。 --release 8 是解决方案。

标签: java checkstyle pmd spotbugs


【解决方案1】:

在 Java 9 之前,您需要使用 Animal Sniffer Plugin 或为 javac 配置正确的 -bootclasspath(在 javac 的交叉编译选项下)以及 -target 选项,或者只使用完全相同的JDK版本。

从 Java 9 开始,有一个新的命令行选项可以解决这个问题:--release。只需使用例如--release 8 为 Java8 和 javac 编译应该会失败并出现编译错误,如果您使用任何 API,该 API 仅在更高版本中可用。

【讨论】:

  • 这正是我们所需要的。谢谢! ``` javac Test.java --release 8 Test.java:7: 错误:找不到符号 List.of(); ^ 符号:方法 of() 位置:接口列表 1 错误```
猜你喜欢
  • 2015-03-26
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
相关资源
最近更新 更多