跳转到内容
GitHub

主题 / 语言

14 Java 与 Kotlin(服务端)

JVM 服务端项目的 JDK 版本与发行版、Maven / Gradle 构建基线、依赖锁定、格式化与静态检查、架构测试、测试、日志、Spring Boot、虚拟线程、数据库访问与迁移工具、依赖漏洞扫描怎么做。

草稿复核于 2026-11-14 · 下次复核 2027-05-1441 条规则 · 硬约束 26 条在 GitHub 上修改

一页结论

  1. JDK 用仍在支持期的 LTS。 非 LTS 版本只用于试验;发布构建不开 preview。编译目标用 --release 或 toolchain 固定,部署清单写明发行版、大版本和 CPU 架构。
  2. 发行版默认 Eclipse Temurin,Oracle JDK 先看许可。 Oracle JDK 的免费条款(NFTC)有期限:旧 LTS 的后续更新会转回需要付费订阅的 OTN 许可,不能默认当成免费。
  3. 构建可复现。 Wrapper 入库并校验;Maven 用 BOM 和固定插件版本,Gradle 用版本目录加锁文件;不用 SNAPSHOT、+、版本范围;依赖只从批准的仓库来。断网交付的项目要真的断网构建一次。
  4. 版本组合按官方矩阵走。 Spring Boot 的 BOM 管它管的依赖,不逐个追最新;Spring Cloud(含 Spring Cloud Alibaba)、Kotlin 插件和 Gradle 的组合都要在官方兼容表内。Spring Boot 版本线停止开源支持前要升级。
  5. 格式和检查交给工具。 Java:Spotless + google-java-format,加 Error Prone(或 SpotBugs)查缺陷;Kotlin:ktlint + detekt。存量问题用基线文件记账。
  6. 架构规则写成 ArchUnit 测试。 依赖方向和「领域代码不依赖框架」在 CI 里跑,不只写在文档里。
  7. 测试用真库。 JUnit + AssertJ,集成测试用 Testcontainers 起同款数据库,不拿 H2 冒充 PostgreSQL 或国产库;Mockito / MockK 只替代不可控的外部边界。
  8. 日志只依赖 SLF4J。 不用 System.out 和 printStackTrace;不吞异常,不吞中断。
  9. 默认 Spring MVC。 虚拟线程和原生镜像要先在真实负载下对比并准备回滚;连接池和下游容量照样要限。
  10. 数据库:一个服务一套访问方式,SQL 全部参数化,生产不让 Hibernate 改表。 迁移默认 Flyway 社区版;Liquibase 从 5.0 起改为 FSL 许可(不是 OSI 开源),选用前核对。
  11. 依赖漏洞扫描进 CI。 OWASP Dependency-Check 或 OSV-Scanner;断网环境要同步漏洞库并记录更新日期。

规则

级别
检查方式
显示 41 条
JVM-001硬约束检查:自动Java / Kotlin(服务端)

生产构建和运行用的 JDK 必须是仍在支持期内的 LTS 版本;非 LTS 版本不作服务端默认

怎么检查:构建插件检查 JDK 版本(Maven Enforcer 的 requireJavaVersion,Gradle toolchain 的 languageVersion);CI 打印 java -version,与发行版的支持路线图比对
为什么、来源
为什么:非 LTS 版本只维护到下一个版本发布,大约半年后就收不到安全补丁;LTS 有多年的更新。
  • 新服务默认用最新的 LTS;客户环境或厂商组件只认证了上一个 LTS 时,可以用上一个,但要在它停止支持前排期升级。
  • Java 的 LTS 大约每两年一个,支持期以所用发行版的路线图为准,不同厂商的期限不同。
JVM-002硬约束检查:自动Java / Kotlin(服务端)

发布构建不得启用 JDK 的预览特性(--enable-preview)和孵化模块(jdk.incubator.*)

怎么检查:CI 扫描构建文件、启动脚本和容器 entrypoint 中的 --enable-preview 和 jdk.incubator;发现即失败
为什么、来源
为什么:预览和孵化特性在后续版本里可能改变或删除;用了预览特性编译的类文件只能在同一个 JDK 大版本上运行,升级 JDK 时会直接启动失败。

想试用新特性,放在不发布的实验分支或独立的试验项目里。

JVM-003硬约束检查:自动Java / Kotlin(服务端)

编译目标版本用 --release 或构建工具的 toolchain 固定,不依赖开发机上恰好装了哪个 JDK

怎么检查:检查 Maven 的 maven.compiler.release 或 Toolchains 配置、Gradle 的 java.toolchain.languageVersion(Kotlin 用 jvmToolchain);CI 在没有预装其他 JDK 的镜像里构建
为什么、来源
为什么:只设 -source / -target 时,高版本 JDK 编译出的代码仍可能调用低版本里没有的 API,部署后才报 NoSuchMethodError。
  • Gradle 自身运行用的 JDK(daemon JDK)和编译代码用的 toolchain 是两回事,分别配置。
  • 断网环境里关闭 toolchain 的自动下载,所需 JDK 预置在构建镜像中。
JVM-004软指导检查:半自动Java / Kotlin(服务端)对外提供服务的后端

部署清单写明 JDK 的发行版、大版本和 CPU 架构;同一产品的构建、测试、生产用同一发行版

怎么检查:评审部署清单或镜像元数据;CI 从运行镜像中读出 java -version 的厂商和版本,与清单比对
为什么、来源
为什么:不同发行版的补丁节奏、支持期和许可不同;只写「Java 21」时,出了问题查不到实际运行的是谁家的哪一版。

要交付到 ARM 服务器或国产操作系统的,JNI 原生库、字体和监控 Agent 也要在目标架构上实际跑过,「Java 跨平台」不等于原生库跨平台。

JVM-005硬约束检查:半自动Java / Kotlin(服务端)

使用 Oracle JDK 前必须核对所用版本当前适用的许可条款;条款要求付费订阅时,要有订阅或换用其他 OpenJDK 发行版

怎么检查:构建镜像和部署清单里扫描 Oracle JDK(java -version 输出的厂商);出现时要求附上许可依据
为什么、来源
为什么:Oracle JDK 的免费条款(NFTC)只覆盖一段时间;官方路线图写明,上一个 LTS 的后续更新改用 OTN 许可,生产使用需要付费订阅。
  • 默认用 Eclipse Temurin 等以 GPLv2 + Classpath Exception 发布的 OpenJDK 发行版,没有这类期限问题。
  • 已经在用 Oracle JDK 的,记录每台机器的版本,在免费期结束前升级到仍免费的版本或切换发行版。
JVM-006硬约束检查:自动Java / Kotlin(服务端)

使用 Maven Wrapper 或 Gradle Wrapper 并入库,CI 和开发者都通过 Wrapper 构建;Gradle Wrapper 设 distributionSha256Sum,CI 校验 wrapper jar

怎么检查:检查仓库里有 mvnw / .mvn/wrapper/ 或 gradlew / gradle/wrapper/;CI 只调用 Wrapper;Gradle 项目在 CI 里跑 wrapper 校验(如 gradle/actions 的 wrapper-validation)
为什么、来源
为什么:不用 Wrapper 时每台机器的构建工具版本不同;wrapper jar 是会被执行的二进制,被替换了就能在构建机上运行任意代码。
JVM-007硬约束检查:自动Java / Kotlin(服务端)

发布构建不得依赖 SNAPSHOT、动态版本(+、latest.release)或版本范围

怎么检查:Maven 用 Enforcer 的 requireReleaseDeps 等规则;Gradle 用 resolutionStrategy.failOnDynamicVersions() 和 failOnChangingVersions()
为什么、来源
为什么:这些版本每次解析结果可能不同,同一个提交今天和明天构建出的产物不一样,也给仓库投毒留了口子。
JVM-008硬约束检查:自动Java / Kotlin(服务端)

Maven 项目的依赖版本集中在 BOM 或 dependencyManagement,所有插件显式写死版本

怎么检查:Maven Enforcer 的 requirePluginVersions;评审子模块中直接写版本号的依赖
为什么、来源
为什么:不写插件版本时,Maven 会用自带的默认版本,换一个 Maven 版本构建行为就变了;版本散落在各模块里,升级时总会漏掉几处。

BOM 只协调版本,不锁定传递依赖的解析结果;发布时另外输出 mvn dependency:tree 和 SBOM 留档。

JVM-009软指导检查:半自动Java / Kotlin(服务端)

Gradle 项目的依赖和插件版本集中写在版本目录(gradle/libs.versions.toml)里,构建脚本只引用别名

怎么检查:评审构建脚本里直接写版本字符串的依赖声明
为什么、来源
为什么:多模块项目版本集中一处才好升级和评审;但版本目录只管声明,不锁住传递依赖,锁定见 JVM-010。
JVM-010硬约束检查:自动Java / Kotlin(服务端)对外提供服务的后端

Gradle 构建的应用开启依赖锁定(dependencyLocking)并提交锁文件;锁文件变化在 PR 里评审

怎么检查:检查构建脚本有 lockAllConfigurations()、仓库有 gradle.lockfile;CI 构建时锁文件与解析结果不一致即失败
为什么、来源
为什么:不锁定时,传递依赖会随上游发布悄悄变化,线上出了问题也复现不出当时的依赖组合。
  • 用 ./gradlew dependencies --write-locks 更新锁文件,更新单独成一个 PR。
  • 供别人引用的库通常不锁定(让使用方决定版本),但 CI 至少用锁定的组合测一遍。
  • 需要防篡改时再开依赖校验(gradle/verification-metadata.xml);首次生成的校验和要人工核对来源,不是生成了就算可信。
JVM-011硬约束检查:自动Java / Kotlin(服务端)

依赖和插件只能从批准的仓库(通常是内部镜像)获取;Gradle 设 repositoriesMode 为 FAIL_ON_PROJECT_REPOS,Maven 在 settings.xml 用 mirrorOf 统一指向内部镜像

怎么检查:CI 检查 settings.gradle(.kts) 的 dependencyResolutionManagement 与 pluginManagement;CI 的 Maven settings.xml 由流水线提供,仓库里的 pom 不得自行添加 <repositories>
为什么、来源
为什么:任何一个模块随手加的第三方仓库,都会成为全项目的依赖来源,被投毒或下线时整个构建受影响。

仓库凭据从 CI 的密钥注入,不写进 settings.xml 或 gradle.properties 入库(见 25)。

另见:25 安全
JVM-012硬约束检查:自动Java / Kotlin(服务端)私有化或断网部署

要求断网交付的项目,必须在无外网的 CI 环境里,从空的本地缓存出发、只用内部镜像完成构建和测试

怎么检查:隔离网络的 CI 任务:清空 ~/.m2 或 ~/.gradle 缓存,只能访问内部仓库和镜像仓库,运行构建、测试和镜像打包
为什么、来源
为什么:开发机上 mvn -o 或 gradle --offline 能过,只说明本机缓存里恰好有;离线参数不会补齐缺失的依赖、JDK 和容器镜像。
另见:TST-035、ARC-032
JVM-013软指导检查:半自动Java / Kotlin(服务端)

使用 Spring Boot 时,它的 BOM 管理的依赖不单独指定版本;确需覆盖的,写明原因并在升级 Spring Boot 时复查

怎么检查:评审 pom 或构建脚本里覆盖受管依赖版本的写法(Maven 的 <version>、属性覆盖,Gradle 的强制版本)
为什么、来源
为什么:BOM 里的版本组合经过框架一起测试;逐个追最新,等于用了一个没人测过的组合。

修安全漏洞需要提前升级某个受管依赖时,用属性覆盖(如 Maven 的版本属性)而不是直接写版本,并在下一次 Spring Boot 升级后删掉覆盖。

JVM-014硬约束检查:半自动Java / Kotlin(服务端)

Spring Boot、Spring Cloud(含 Spring Cloud Alibaba 等第三方套件)的版本组合必须在官方兼容表内,不自行搭配

怎么检查:仓库里记录所用组合和对应的官方兼容表链接;升级 PR 对照兼容表评审,并跑完整集成测试
为什么、来源
为什么:这些套件按 Spring Boot 的版本线发布,官方表没覆盖的组合常在运行时才出现类找不到或配置不生效。

第三方套件(如 Spring Cloud Alibaba)跟进 Spring Boot 新版本往往滞后;它的兼容表没列出的 Spring Boot 版本,就先停在表里的版本上。

JVM-015硬约束检查:半自动Java / Kotlin(服务端)

Kotlin 项目使用的 Gradle 版本必须在所用 Kotlin Gradle 插件官方声明的兼容范围内,升级任何一方前先查兼容表

怎么检查:升级 Kotlin 或 Gradle 的 PR 附上兼容表链接;CI 打印 ./gradlew --version 和 Kotlin 插件版本
为什么、来源
为什么:Kotlin 插件只对一段 Gradle 版本给出完整支持;超出上限时可能出现弃用警告甚至构建失败。

因此 Kotlin 服务端项目不一定能用最新的 Gradle 大版本。Android 项目还受 AGP 约束,见 29。

JVM-016硬约束检查:自动Java / Kotlin(服务端)

生产使用的 Spring Boot 版本线必须在开源支持期内,或者有商业支持;停止支持前完成升级

怎么检查:CI 读取所用 Spring Boot 版本,与官方支持版本表比对;离开开源支持期仍无商业支持时失败
参考值:官方政策写明每个小版本线至少有 13 个月开源支持,大版本最后一个小版本线另有更长的商业支持;具体日期以官方支持表为准。
为什么、来源
为什么:版本线停止支持后不再发布安全修复,而 Spring Boot 管理着大量传递依赖的版本。
JVM-017软指导检查:人工Java / Kotlin(服务端)对外提供服务的后端

新的 Web 服务默认用 Spring MVC(阻塞模型);只有端到端都是非阻塞的场景才用 WebFlux

怎么检查:评审技术选型说明
为什么、来源
为什么:用了 JDBC 等阻塞调用的 WebFlux 服务,会把事件循环线程卡住,比 MVC 更慢也更难排查。
JVM-018软指导检查:半自动Java / Kotlin(服务端)

使用 Spring Boot 当前大版本时,JSON 用它默认的 Jackson 大版本;需要引入另一个 Jackson 大版本的,写明原因并加序列化契约测试

怎么检查:依赖树检查同时出现两个 Jackson 大版本;评审对应的契约测试
为什么、来源
为什么:两个 Jackson 大版本的包名和默认行为不同,混用时注解和模块可能只对其中一个生效,序列化结果悄悄变化。
JVM-019硬约束检查:半自动Java / Kotlin(服务端)对外提供服务的后端

生产环境不得把 Actuator 管理端点暴露到公网;只暴露需要的端点,健康检查分开 liveness 和 readiness

怎么检查:检查 management.endpoints.web.exposure.include 和管理端口配置;部署层确认管理端口不对外
为什么、来源
为什么:env、heapdump 等端点会泄露配置、密钥和内存内容;把数据库故障算进 liveness 会让下游一抖就全部重启。
JVM-020软指导检查:半自动Java / Kotlin(服务端)对外提供服务的后端

服务开启优雅停机,并设置每个停机阶段的最长等待时间,小于编排平台给的终止宽限期

怎么检查:检查 server.shutdown 和 spring.lifecycle.timeout-per-shutdown-phase;集成测试发送 SIGTERM,断言进行中的请求完成
为什么、来源
为什么:直接退出会中断进行中的请求和事务;等待时间超过平台宽限期,进程会被强杀,等于没设。
JVM-021软指导检查:人工Java / Kotlin(服务端)对外提供服务的后端

启用虚拟线程或 GraalVM 原生镜像前,用真实负载和默认方案做对比,记录结果和回滚开关;连接池、并发数等上限照常设置

怎么检查:评审启用说明:对比数据(吞吐、延迟分位、内存)、已知不兼容项、回滚方式
为什么、来源
为什么:虚拟线程只对阻塞 I/O 为主的负载有帮助,数据库连接池和下游容量仍是瓶颈;原生镜像对反射、动态代理、JDBC 驱动和监控 Agent 都有兼容代价。

Kotlin 协程或 Reactor 的代码不要再叠加虚拟线程就宣称性能提升;排查时看线程转储和 JFR。

JVM-022硬约束检查:自动Java / Kotlin(服务端)

Java 代码用一个格式器(默认 google-java-format)统一格式,通过 Spotless 在 CI 里检查

怎么检查:CI 运行 spotlessCheck(Gradle)或 spotless:check(Maven),有差异即失败
为什么、来源
为什么:格式交给工具后评审不再讨论空白和导入顺序;Agent 和人写出的代码格式一致。

Checkstyle 若与格式器同时使用,只开格式器管不到的规则(命名、禁止的 API 等),不重复检查缩进和换行,否则两者会互相打架。

JVM-023硬约束检查:自动Java / Kotlin(服务端)

Kotlin 代码用 ktlint 格式化和检查(可通过 Spotless 调用),用 detekt 做静态检查;两者都在 CI 里运行

怎么检查:CI 运行 ktlintCheck 或 spotlessCheck,以及 detekt;有新增问题即失败
为什么、来源
为什么:ktlint 管格式,detekt 管代码异味和潜在错误,两者分工不重叠。
  • 存量项目用 detekt 的基线文件记录已有问题,只拦新增的;不要一上来就把全部规则设成错误。
  • 只用工具的稳定版,不把预发布版放进基线。
来源:ktlint、detekt另见:COD-040
JVM-024软指导检查:自动Java / Kotlin(服务端)

Java 项目在格式器之外,至少启用一种查缺陷的静态检查(Error Prone 或 SpotBugs),并在 CI 里阻断新增的错误级问题

怎么检查:CI 编译时启用 Error Prone,或运行 SpotBugs;配置里按规则编号写明开启和关闭的规则
为什么、来源
为什么:格式正确不等于逻辑正确;这类工具能在编译时发现空指针、资源未关闭、equals 与 hashCode 不一致等问题。
  • 默认 Error Prone(编译期运行,反馈快);需要空安全检查时加 NullAway。
  • javac 打开 -Xlint,新代码不新增警告。
  • 抑制警告必须写明具体规则,如 @SuppressWarnings("unchecked"),不用 "all"(见 COD-039)。
来源:Error Prone、SpotBugs、NullAway另见:COD-039
JVM-025硬约束检查:自动Java / Kotlin(服务端)

Kotlin 代码不用 GlobalScope 启动协程;!! 非空断言只在有注释说明为什么不会为空时使用

怎么检查:detekt 启用 GlobalCoroutineUsage 和 UnsafeCallOnNullableType;例外处用带规则名的 @Suppress 并写理由
为什么、来源
为什么:GlobalScope 里的协程不随请求或服务的生命周期取消,会泄漏;!! 把编译期的空安全变成运行时的空指针。

服务边界的请求和返回类型显式写出可空性;lateinit 只用于框架注入,不用来掩盖初始化顺序问题。

来源:detekt另见:COD-035
JVM-026软指导检查:自动Java / Kotlin(服务端)

模块或包之间的依赖方向写成 ArchUnit 测试,与单元测试一起在 CI 里运行

怎么检查:测试代码里有 ArchUnit 规则(如领域包不依赖 Spring、JPA、Web 包;模块间无环),CI 运行
为什么、来源
为什么:依赖方向只写在文档里会慢慢被破坏;写成测试,违规的 PR 直接失败。
  • 存量违规用 ArchUnit 的冻结规则(FreezingArchRule)记录,只拦新增的。
  • Spring 项目按业务模块组织代码时,可以用 Spring Modulith 校验模块边界。
  • 规则要有故意违规的负例,证明检查真的会失败(见 ARC-011)。
JVM-027软指导检查:人工Java / Kotlin(服务端)

单元测试用 JUnit 平台(Jupiter 编程模型)加 AssertJ 断言;Kotlin 项目可用 Kotest 断言和 MockK

怎么检查:评审新增测试的写法和依赖
为什么、来源
为什么:统一的测试框架让 IDE、构建工具和 CI 报告都能直接识别;AssertJ 的失败信息比 assertTrue 清楚得多。

测试依赖的版本交给 Spring Boot 或 JUnit 的 BOM 管理,不逐个写死。

JVM-028硬约束检查:半自动Java / Kotlin(服务端)

涉及数据库、消息队列、缓存的集成测试用 Testcontainers 拉起与生产同款同大版本的组件,不用 H2 等内存库冒充

怎么检查:依赖检查发现测试范围引入 H2、HSQLDB 而生产不是该数据库时要求说明;评审集成测试的依赖启动方式
为什么、来源
为什么:H2 的 SQL 方言、锁、约束和类型行为与 PostgreSQL、国产库都不同,在 H2 上通过的查询上线照样会错。
  • Spring Boot 项目用 @ServiceConnection 把容器连接信息注入应用,不手写端口和地址。
  • 镜像固定摘要,内网环境从内部镜像仓库拉取(见 TST-013)。
  • 国产数据库没有可用镜像时,用隔离的专用测试实例,测试后清理。
JVM-029软指导检查:人工Java / Kotlin(服务端)

Mockito / MockK 只替代不可控的外部边界;对外 HTTP 依赖用 WireMock 等 HTTP 模拟,不把数据库和事务 mock 掉

怎么检查:评审测试中被 mock 的对象:Repository、DataSource、事务管理器被 mock 时要说明理由
为什么、来源
为什么:mock 掉数据库后,SQL、事务边界和序列化的错误都测不出来,测试只是在验证 mock 自己。
来源:Mockito、WireMock另见:TST-039
JVM-030硬约束检查:自动Java / Kotlin(服务端)

应用代码只依赖 SLF4J 接口打日志;不用 System.out、System.err 和 printStackTrace();运行时只保留一个日志实现

怎么检查:ArchUnit 的 NO_CLASSES_SHOULD_ACCESS_STANDARD_STREAMS 等规则或 Checkstyle 禁用这些调用;依赖检查发现多个 SLF4J 绑定时失败
为什么、来源
为什么:标准输出没有级别和结构,进不了日志系统;同时存在多个日志实现时,实际生效的是哪个取决于类路径顺序。

Spring Boot 默认的 Logback 即可;换 Log4j2 要排除默认实现。用占位符 log.info("order {} paid", id) 或键值 API,不拼接字符串;Spring Boot 服务的生产日志用框架自带的结构化格式(logging.structured.format.*)输出并带追踪编号,不需要额外的编码器依赖。字段约定见 02。

JVM-031硬约束检查:自动Java / Kotlin(服务端)

不写空的 catch;捕获 InterruptedException 后必须恢复中断标志或向上抛出

怎么检查:Error Prone、SpotBugs 或 detekt(SwallowedException、EmptyCatchBlock)检查;评审 catch (InterruptedException e) 的处理
为什么、来源
为什么:吞掉异常会让失败静默地变成成功;吞掉中断会让线程池停机和任务取消失效。
来源:Error Prone、detekt另见:COD-010
JVM-032硬约束检查:自动Java / Kotlin(服务端)

需要关闭的资源(流、连接、语句、结果集)用 try-with-resources 或 Kotlin 的 use 管理

怎么检查:SpotBugs 的资源未关闭检查(OBL、ODR 类规则)或 Error Prone 的相关检查;评审手写 finally { close() }
为什么、来源
为什么:异常路径上漏关一个连接,连接池就少一个,压力大时很快耗尽。
来源:SpotBugs
JVM-033硬约束检查:半自动Java / Kotlin(服务端)

不用 Java 原生序列化(ObjectInputStream)读取不可信数据;不得不用时设置反序列化过滤器;Jackson 不开启全局多态类型(default typing)

怎么检查:SpotBugs 加 find-sec-bugs 检查 ObjectInputStream 和 Jackson default typing;评审 jdk.serialFilter 配置
为什么、来源
为什么:反序列化不可信数据可以触发类路径上的「利用链」直接执行代码,是 JVM 上最常见的远程代码执行来源之一。
JVM-034硬约束检查:半自动Java / Kotlin(服务端)

HTTP 客户端(JDK HttpClient、RestClient、Ktor Client 等)必须显式设置连接超时和读取或请求超时

怎么检查:评审客户端的创建代码;集成测试用 WireMock 模拟慢响应,断言在超时内失败
为什么、来源
为什么:JDK HttpClient 默认没有请求超时;下游挂住时请求线程会一直占着,最终拖垮整个服务。

重试和熔断用 Resilience4j 或框架自带能力,只对幂等操作重试(见 COD-034)。

JVM-035硬约束检查:半自动Java / Kotlin(服务端)

SQL 参数一律用绑定参数(PreparedStatement、JdbcClient / JdbcTemplate 参数、JPA 参数、MyBatis 的 #{}),不拼接用户输入;MyBatis 的 ${} 只能接白名单里的标识符

怎么检查:find-sec-bugs 的 SQL 注入检查;扫描 Mapper 文件中的 ${;评审动态 SQL 的标识符来源
为什么、来源
为什么:拼接 SQL 是注入漏洞的直接来源;${} 是原样替换,和拼接字符串没有区别。
来源:find-sec-bugs另见:25 安全
JVM-036硬约束检查:自动Java / Kotlin(服务端)

生产环境不得用 Hibernate 自动建表或改表(ddl-auto 为 update、create、create-drop);表结构只通过迁移工具变更

怎么检查:CI 检查生产配置中 spring.jpa.hibernate.ddl-auto 只能是 none 或 validate
为什么、来源
为什么:自动改表没有评审、没有记录,可能直接删列丢数据,多副本同时启动时还会互相冲突。

迁移的原则(向前修复、单独的发布步骤、不在每个实例启动时跑)见 17。

JVM-037软指导检查:人工Java / Kotlin(服务端)

一个服务只选一种主要的数据访问方式(JDBC / JdbcClient、JPA、jOOQ、MyBatis 之一)

怎么检查:评审依赖树和数据访问层:出现第二种方式时要求说明
为什么、来源
为什么:几套并存时,事务、批量写入、缓存和错误处理各有一套写法,事务边界很容易出错。

报表等少量复杂查询可以在 JPA 项目里用 JdbcClient 补充,但要在说明里写清边界。

JVM-038软指导检查:半自动Java / Kotlin(服务端)对外提供服务的后端

JPA 实体不直接作为接口的请求或响应;用单独的 DTO 或查询投影

怎么检查:ArchUnit 规则:Controller 的方法签名不得出现 @Entity 类型
为什么、来源
为什么:直接返回实体会触发懒加载和 N+1 查询,还会把内部字段暴露出去;直接接收实体会被批量赋值改掉不该改的字段。
JVM-039软指导检查:半自动Java / Kotlin(服务端)

使用 openGauss 等「兼容 PostgreSQL」的国产数据库时,确认驱动类名不与 pgJDBC 冲突,并在目标数据库上跑迁移和集成测试

怎么检查:依赖树检查同时存在 pgJDBC 和厂商驱动;在目标数据库实例上跑迁移、增删改查和并发测试
为什么、来源
为什么:部分 openGauss 驱动沿用 org.postgresql.Driver 类名,两个驱动同时在类路径上时,加载哪个取决于顺序。
JVM-040硬约束检查:自动Java / Kotlin(服务端)

CI 对 JVM 依赖运行漏洞扫描(OWASP Dependency-Check 或 OSV-Scanner),按项目设定的严重级别阻断;断网环境使用内部同步的漏洞库并记录库的更新日期

怎么检查:CI 运行 Dependency-Check 的 Maven / Gradle 插件(设 failBuildOnCVSS)或 osv-scanner;误报写进抑制文件并附理由和到期日
为什么、来源
为什么:JVM 项目的传递依赖很多,已知漏洞大多出在没直接声明的依赖里。

Dependency-Check 下载 NVD 数据需要 API key,按密钥管理(见 25)。没有同步漏洞库却显示「通过」,不算扫描过。SBOM 用 CycloneDX 的 Maven / Gradle 插件在构建时生成,随发布物保存,比事后扫描 JAR 更准确。

JVM-041软指导检查:自动Java / Kotlin(服务端)供别人引用的库或 SDK

供别人引用的库不使用 Spring Boot 的打包插件;对公开 API 做二进制兼容检查(Java 用 japicmp,Kotlin 用 Kotlin 插件的 ABI 校验)

怎么检查:依赖检查库模块没有 spring-boot-maven-plugin 或 org.springframework.boot 插件;CI 运行 japicmp 或 ABI 校验任务,对比上一个发布版本
为什么、来源
为什么:Boot 插件会把库打成可执行 JAR,别人没法正常依赖;源码兼容不等于二进制兼容,删一个重载或改返回类型,使用方不重新编译就会运行时报错。

独立的 binary-compatibility-validator 插件已进入维护模式,新功能转到 Kotlin Gradle 插件内置的 ABI 校验(目前仍是实验特性)。

选型

类别默认备选(何时用)不推荐
JDK 发行版Eclipse Temurin(Adoptium) · OpenJDK 发行版为 GPLv2 + Classpath Exception;Oracle JDK 按 NFTC 或 OTN 条款,视版本而定
Amazon Corretto、Microsoft Build of OpenJDK、Red Hat build of OpenJDK(部署在对应厂商的云或系统上,想要厂商一并支持)
Azul Zulu、BellSoft Liberica(需要商业支持合同或更长的补丁期)
国内厂商的 OpenJDK 发行版(客户的国产 CPU 或操作系统只认证了某个发行版;先核对其支持期和更新节奏)
未核对许可就用 Oracle JDK:免费条款有期限,过期后的更新需要付费订阅(JVM-005)
开发、CI、生产各用各的发行版:补丁节奏不同,问题难以复现
构建工具Maven(Wrapper + Spring Boot parent / BOM + Enforcer) · Maven、Gradle 均为 Apache-2.0
Java 为主的 Spring Boot 服务
Gradle(Kotlin DSL + 版本目录 + 依赖锁定)(Kotlin 项目、多模块大仓、需要自定义构建逻辑;版本受 Kotlin 插件兼容表约束(JVM-015))
同一仓库同时维护两套构建:依赖和插件配置会分叉
Web 框架Spring Boot(Spring MVC) · 以上框架均为 Apache-2.0
Quarkus(对内存和启动时间敏感,或计划用原生镜像;选它的 LTS 版本线)
Micronaut(想要编译期依赖注入、少用反射)
Ktor(Kotlin 写的轻量 HTTP 服务,不需要 Spring 生态)
用 JDBC 的服务选 WebFlux:阻塞调用会卡住事件循环(JVM-017)
自己写 HTTP 框架:现成框架已解决路由、校验、安全和可观测性
数据访问Spring JDBC 的 JdbcClient / JdbcTemplate · Hibernate ORM 从 7.0 起为 Apache-2.0(更早版本为 LGPL-2.1);jOOQ 开源版为 Apache-2.0,只支持开源数据库,商业数据库需商业许可;MyBatis、Exposed 为 Apache-2.0
SQL 简单、希望完全掌控 SQL 的服务
JPA(Hibernate)(领域模型有聚合和对象关系,团队熟悉 ORM 的会话和懒加载)
jOOQ(复杂报表和联表查询,想要类型安全的 SQL;用于商业数据库时需要付费版本)
MyBatis(团队已有大量 Mapper,或高度手写 SQL)
Exposed(纯 Kotlin、不依赖 Spring 的项目)
一个服务并存多套访问层:事务和错误处理各有一套(JVM-037)
自研「万能 Repository」:SQL 不透明,难审计难维护
PostgreSQL 驱动与连接池pgJDBC + HikariCP(Spring Boot 默认) · pgJDBC 为 BSD-2-Clause;HikariCP 为 Apache-2.0
数据库厂商提供的 JDBC 驱动(使用国产数据库(注意 JVM-039))
Agroal(Quarkus 项目)
不设上限的连接池或每次请求新建连接:压垮数据库
数据库迁移工具Flyway 社区版 · Flyway 社区版为 Apache-2.0,由 Redgate 维护;撤销迁移(undo)等功能只在付费的 Teams / Enterprise 版中,部分数据库也需付费版。Liquibase 社区版从 5.0 起为 FSL-1.1-ALv2:允许内部和生产使用,禁止拿去做与 Liquibase 竞争的商业产品或服务,每个版本发布两年后转为 Apache-2.0;它不是 OSI 认可的开源许可,更早的版本仍是 Apache-2.0
以 SQL 文件为迁移单位的项目;迁移原则见 17
Liquibase 社区版(要用同一套变更集描述支持多种数据库,或需要它的变更集管理能力;先确认 FSL 许可符合项目的使用和分发方式)
Hibernate 的 ddl-auto 改生产库:无评审、无记录、可能丢数据(JVM-036)
在应用里手写 DDL 执行逻辑:多副本同时执行、无法审查
格式化Spotless + google-java-format(Java);ktlint(Kotlin) · Spotless、google-java-format 为 Apache-2.0;ktlint 为 MIT
palantir-java-format(团队想要更宽的行长,全仓一起切换)
只靠 IDE 的格式化设置:不同人不同配置,CI 无法检查
静态检查Error Prone(Java,编译期);detekt(Kotlin) · Error Prone、detekt 为 Apache-2.0;NullAway 为 MIT;SpotBugs、Checkstyle 为 LGPL-2.1;PMD 为 BSD 风格许可。都是构建时独立运行的工具,不进入产品分发(口径见 27)
NullAway(要在 Java 代码里强制空安全;作为 Error Prone 插件运行)
SpotBugs(加 find-sec-bugs)(想按字节码查资源泄漏、并发和安全问题)
Checkstyle(要强制命名、禁用 API 等格式器管不到的规则)
PMD(团队已有 PMD 规则集)
SonarQube 自部署(有资源维护服务端,需要跨项目的质量看板)
一次开启全部规则:误报淹没真问题;用基线只拦新增(COD-024)
架构测试ArchUnit · ArchUnit、Spring Modulith 均为 Apache-2.0
Spring Modulith(Spring 项目按业务模块组织,想同时校验模块边界并生成模块文档)
—
测试JUnit(Jupiter)+ AssertJ + Mockito;集成测试用 Testcontainers · JUnit 为 EPL-2.0;AssertJ、MockK、WireMock 为 Apache-2.0;Mockito、Testcontainers 为 MIT;JMH 为 GPLv2 + Classpath Exception(只在测试中使用)
MockK、Kotest(Kotlin 项目)
WireMock(模拟对外 HTTP 依赖)
JMH(微基准测试;不要用单次计时估算性能)
H2 冒充生产数据库:方言和行为不同(JVM-028)
日志SLF4J + Logback(Spring Boot 默认) · SLF4J 为 MIT;Logback 为 EPL-1.0 / LGPL-2.1 双许可;Log4j2 为 Apache-2.0
Log4j2(存量项目已在用,或需要它的异步日志特性;排除默认的 Logback)
System.out 和 printStackTrace:无级别、无结构(JVM-030)
HTTP 客户端与容错Spring 的 RestClient(或 JDK HttpClient)+ Resilience4j · Resilience4j 为 Apache-2.0
Ktor Client(Kotlin / Ktor 项目)
OkHttp、Apache HttpClient(需要它们特有的连接管理或拦截器)
在业务代码里手写重试循环:容易无上限重试、重试非幂等操作
依赖漏洞扫描OWASP Dependency-Check(Maven / Gradle 插件) · Dependency-Check、OSV-Scanner 为 Apache-2.0
OSV-Scanner(想直接读锁文件或 SBOM,或不想维护 NVD 数据同步)
Trivy 等通用扫描器(还要扫容器镜像和系统包(见 25))
—
SBOM 生成CycloneDX Maven / Gradle 插件 · Apache-2.0——
库的二进制兼容检查japicmp(Java);Kotlin Gradle 插件内置的 ABI 校验(Kotlin) · 均为 Apache-2.0
binary-compatibility-validator(已在用的 Kotlin 项目;该插件已进入维护模式)
—
JDK 发行版
Eclipse Temurin(Adoptium) · OpenJDK 发行版为 GPLv2 + Classpath Exception;Oracle JDK 按 NFTC 或 OTN 条款,视版本而定
备选:Amazon Corretto、Microsoft Build of OpenJDK、Red Hat build of OpenJDK(部署在对应厂商的云或系统上,想要厂商一并支持);Azul Zulu、BellSoft Liberica(需要商业支持合同或更长的补丁期);国内厂商的 OpenJDK 发行版(客户的国产 CPU 或操作系统只认证了某个发行版;先核对其支持期和更新节奏)
不推荐:未核对许可就用 Oracle JDK;开发、CI、生产各用各的发行版
构建工具
Maven(Wrapper + Spring Boot parent / BOM + Enforcer) · Maven、Gradle 均为 Apache-2.0
备选:Gradle(Kotlin DSL + 版本目录 + 依赖锁定)(Kotlin 项目、多模块大仓、需要自定义构建逻辑;版本受 Kotlin 插件兼容表约束(JVM-015))
不推荐:同一仓库同时维护两套构建
Web 框架
Spring Boot(Spring MVC) · 以上框架均为 Apache-2.0
备选:Quarkus(对内存和启动时间敏感,或计划用原生镜像;选它的 LTS 版本线);Micronaut(想要编译期依赖注入、少用反射);Ktor(Kotlin 写的轻量 HTTP 服务,不需要 Spring 生态)
不推荐:用 JDBC 的服务选 WebFlux;自己写 HTTP 框架
数据访问
Spring JDBC 的 JdbcClient / JdbcTemplate · Hibernate ORM 从 7.0 起为 Apache-2.0(更早版本为 LGPL-2.1);jOOQ 开源版为 Apache-2.0,只支持开源数据库,商业数据库需商业许可;MyBatis、Exposed 为 Apache-2.0
备选:JPA(Hibernate)(领域模型有聚合和对象关系,团队熟悉 ORM 的会话和懒加载);jOOQ(复杂报表和联表查询,想要类型安全的 SQL;用于商业数据库时需要付费版本);MyBatis(团队已有大量 Mapper,或高度手写 SQL);Exposed(纯 Kotlin、不依赖 Spring 的项目)
不推荐:一个服务并存多套访问层;自研「万能 Repository」
PostgreSQL 驱动与连接池
pgJDBC + HikariCP(Spring Boot 默认) · pgJDBC 为 BSD-2-Clause;HikariCP 为 Apache-2.0
备选:数据库厂商提供的 JDBC 驱动(使用国产数据库(注意 JVM-039));Agroal(Quarkus 项目)
不推荐:不设上限的连接池或每次请求新建连接
数据库迁移工具
Flyway 社区版 · Flyway 社区版为 Apache-2.0,由 Redgate 维护;撤销迁移(undo)等功能只在付费的 Teams / Enterprise 版中,部分数据库也需付费版。Liquibase 社区版从 5.0 起为 FSL-1.1-ALv2:允许内部和生产使用,禁止拿去做与 Liquibase 竞争的商业产品或服务,每个版本发布两年后转为 Apache-2.0;它不是 OSI 认可的开源许可,更早的版本仍是 Apache-2.0
备选:Liquibase 社区版(要用同一套变更集描述支持多种数据库,或需要它的变更集管理能力;先确认 FSL 许可符合项目的使用和分发方式)
不推荐:Hibernate 的 ddl-auto 改生产库;在应用里手写 DDL 执行逻辑
格式化
Spotless + google-java-format(Java);ktlint(Kotlin) · Spotless、google-java-format 为 Apache-2.0;ktlint 为 MIT
备选:palantir-java-format(团队想要更宽的行长,全仓一起切换)
不推荐:只靠 IDE 的格式化设置
静态检查
Error Prone(Java,编译期);detekt(Kotlin) · Error Prone、detekt 为 Apache-2.0;NullAway 为 MIT;SpotBugs、Checkstyle 为 LGPL-2.1;PMD 为 BSD 风格许可。都是构建时独立运行的工具,不进入产品分发(口径见 27)
备选:NullAway(要在 Java 代码里强制空安全;作为 Error Prone 插件运行);SpotBugs(加 find-sec-bugs)(想按字节码查资源泄漏、并发和安全问题);Checkstyle(要强制命名、禁用 API 等格式器管不到的规则);PMD(团队已有 PMD 规则集);SonarQube 自部署(有资源维护服务端,需要跨项目的质量看板)
不推荐:一次开启全部规则
架构测试
ArchUnit · ArchUnit、Spring Modulith 均为 Apache-2.0
备选:Spring Modulith(Spring 项目按业务模块组织,想同时校验模块边界并生成模块文档)
测试
JUnit(Jupiter)+ AssertJ + Mockito;集成测试用 Testcontainers · JUnit 为 EPL-2.0;AssertJ、MockK、WireMock 为 Apache-2.0;Mockito、Testcontainers 为 MIT;JMH 为 GPLv2 + Classpath Exception(只在测试中使用)
备选:MockK、Kotest(Kotlin 项目);WireMock(模拟对外 HTTP 依赖);JMH(微基准测试;不要用单次计时估算性能)
不推荐:H2 冒充生产数据库
日志
SLF4J + Logback(Spring Boot 默认) · SLF4J 为 MIT;Logback 为 EPL-1.0 / LGPL-2.1 双许可;Log4j2 为 Apache-2.0
备选:Log4j2(存量项目已在用,或需要它的异步日志特性;排除默认的 Logback)
不推荐:System.out 和 printStackTrace
HTTP 客户端与容错
Spring 的 RestClient(或 JDK HttpClient)+ Resilience4j · Resilience4j 为 Apache-2.0
备选:Ktor Client(Kotlin / Ktor 项目);OkHttp、Apache HttpClient(需要它们特有的连接管理或拦截器)
不推荐:在业务代码里手写重试循环
依赖漏洞扫描
OWASP Dependency-Check(Maven / Gradle 插件) · Dependency-Check、OSV-Scanner 为 Apache-2.0
备选:OSV-Scanner(想直接读锁文件或 SBOM,或不想维护 NVD 数据同步);Trivy 等通用扫描器(还要扫容器镜像和系统包(见 25))
SBOM 生成
CycloneDX Maven / Gradle 插件 · Apache-2.0
库的二进制兼容检查
japicmp(Java);Kotlin Gradle 插件内置的 ABI 校验(Kotlin) · 均为 Apache-2.0
备选:binary-compatibility-validator(已在用的 Kotlin 项目;该插件已进入维护模式)
  • Web 框架:这是按约束选,不是性能排名;要比较就用目标业务和部署资源实际跑基准。
  • 数据访问:MyBatis-Plus 的逻辑删除、租户条件、分页插件会自动改写 SQL,用之前要清楚它生成了什么;租户隔离不能只靠插件(见 19)。
  • 数据库迁移工具:社区版不提供 undo,回退靠向前修复(见 17)。国产数据库的支持不能从 PostgreSQL 支持外推,要实际跑一遍。
  • 依赖漏洞扫描:Dependency-Check 的代码仓库已从个人账号迁到 dependency-check 组织,旧仓库已归档。

常见错误

错误做法:新服务选非 LTS 的最新 JDK 上生产
应该:用仍在支持期的 LTS(JVM-001)
错误做法:默认 Oracle JDK 免费,不查当前版本适用的条款
应该:用 Temurin 等 OpenJDK 发行版,或核对许可(JVM-005)
错误做法:给每个 starter 都显式写上最新补丁版本
应该:交给 Spring Boot BOM 管理(JVM-013)
错误做法:Kotlin 项目把 Kotlin 插件和 Gradle 都升到最新,不查兼容表
应该:按 Kotlin 插件声明的 Gradle 范围选版本(JVM-015)
错误做法:在开发机上 mvn -o 构建成功就宣称支持离线交付
应该:在无外网 CI 里从空缓存构建(JVM-012)
错误做法:只在 H2 上测试 PostgreSQL 或国产库的 SQL
应该:Testcontainers 或隔离的目标库实例(JVM-028)
错误做法:用 Mockito 把 Repository 和事务全部 mock 掉
应该:数据库走真实集成测试,mock 只用于不可控的外部边界(JVM-029)
错误做法:生产开着 ddl-auto=update
应该:Flyway / Liquibase 管理表结构(JVM-036)
错误做法:JPA 实体直接作为 JSON 返回
应该:DTO 或查询投影(JVM-038)
错误做法:多副本服务直接用 @Scheduled 跑只能执行一次的任务
应该:用带集群锁的调度方案(选型见 18)
错误做法:因为 Spotless 没报错就跳过评审
应该:格式只是第一道;缺陷检查和人工评审照常进行
错误做法:不看许可证就引入 XXL-JOB(GPL-3.0)、Camunda 8 自托管或商业数据库上的 jOOQ
应该:引入前按 27 的口径审查许可

待确认

下面的内容还没核实或待补调研,不要当成规则执行。

  • 当前 Java LTS 为 Java 25,下一个 LTS 按 Oracle 路线图为 Java 29(2027-09,路线图注明可能变化);Oracle JDK 21 在 2026-09 之后的更新改用 OTN 许可。以上来自 Oracle 路线图,版本号不写进规则,由版本账本跟踪
  • Spring Boot 各版本线的具体支持截止日期(如 4.0、4.1)只从第三方汇总页看到,未在官方支持表逐条核对;规则只引用官方政策(每个小版本线至少 13 个月开源支持)
  • Gradle 当前大版本为 9(官方发布说明核实);原报告「Kotlin 插件完整支持的 Gradle 上限低于最新 Gradle」的具体上限未在 Kotlin 官方兼容表复核,升级时以兼容表为准
  • Flyway 社区版仍为 Apache-2.0、Redgate 维护;Teams / Enterprise 的现行功能划分和哪些数据库需要付费版,只从较早的 Redgate 页面看到,未核实 2026 年的现状
  • Liquibase FSL 对「把 Liquibase 随产品一起分发给客户」是否构成竞争性使用,官方博客没有直接说明;私有化交付要随产品带上 Liquibase 时,需按 27 的口径单独确认
  • Spring Cloud Alibaba 当前版本对新 Spring Boot 版本线的兼容情况(原报告称只覆盖较早的一条版本线)未复核
  • 原报告的 Seata、Nacos、Dubbo、Testcontainers 等版本与日期存在自相矛盾或未核实,均未写入;中间件选型见 18
  • EasyExcel、Valiktor、QuickTheories 的维护状态未核实(疑似停止维护),未写入选型
  • 选型中的许可证:Hibernate、Liquibase、Flyway 已按官方说明核实,其余按 GitHub 仓库的 LICENSE 识别结果填写(google-java-format、PMD、Logback、jOOQ 的仓库未给出标准识别,按官方说明填写),未逐个阅读许可全文
  • 2026-11-14 新增的来源(S03、S08、S10、S11–S15、S19、S20、S26–S32、S34、S35、S37–S43、S46–S50、S56–S58、S60)只确认链接有效且为官方入口,未逐页核对与规则对应的具体段落
  • 待补调研:Spring Boot 最新大版本和 Spring Framework 大版本的系统性变化(Jakarta EE 基线、空值注解、starter 改名等),原报告只讲了 Jackson 3 和 starter 改名
  • 待补调研:Gradle 版的 Spring Boot / Ktor 服务模板和 Maven 版库模板,需实际构建通过后再发布
  • 待补调研:国产 JDK 发行版(面向国产 CPU 的发行版)的支持期与更新节奏;阿里巴巴 Java 开发手册中可直接采纳的条目
  • 待补调研:容器中 JVM 的内存与 CPU 参数(按容器限额设置堆大小等)缺少有出处的建议

来源

  1. S01 Oracle Java SE Support Roadmap · Oracle · 官方文档 · 核实于 2026-11-14
  2. S02 Spring Support Policy · Spring · 官方文档 · 核实于 2026-11-14
  3. S03 Eclipse Temurin(Adoptium) · Eclipse Adoptium · 官方文档 · 核实于 2026-11-14
  4. S04 Spring Boot: Build Systems(依赖管理与 starter) · Spring · 官方文档 · 核实于 2026-11-13
  5. S05 Spring Boot Maven Plugin: Using the Plugin · Spring · 官方文档 · 核实于 2026-11-13
  6. S06 Spring Cloud Alibaba 版本说明 · Alibaba · 官方文档 · 核实于 2026-11-13
  7. S07 Kotlin: Configure a Gradle project(Gradle 兼容表) · JetBrains · 官方文档 · 核实于 2026-11-13
  8. S08 Gradle: Toolchains for JVM projects · Gradle · 官方文档 · 核实于 2026-11-14
  9. S09 Gradle: Compatibility Matrix · Gradle · 官方文档 · 核实于 2026-11-13
  10. S10 Oracle No-Fee Terms and Conditions(NFTC) · Oracle · 官方文档 · 核实于 2026-11-14
  11. S11 Apache Maven Wrapper · Apache Maven · 官方文档 · 核实于 2026-11-14
  12. S12 Gradle: The Gradle Wrapper · Gradle · 官方文档 · 核实于 2026-11-14
  13. S13 gradle/actions(含 wrapper-validation) · Gradle · 官方文档 · 核实于 2026-11-14
  14. S14 Maven Enforcer Built-In Rules · Apache Maven · 官方文档 · 核实于 2026-11-14
  15. S15 Gradle: Version Catalogs · Gradle · 官方文档 · 核实于 2026-11-14
  16. S16 Gradle: Locking Dependency Versions · Gradle · 官方文档 · 核实于 2026-11-13
  17. S17 Gradle: Verifying Dependencies · Gradle · 官方文档 · 核实于 2026-11-13
  18. S18 Introducing Jackson 3 support in Spring · Spring · 官方文档 · 2025-10-07 · 核实于 2026-11-13
  19. S19 Spring Boot: Actuator Endpoints · Spring · 官方文档 · 核实于 2026-11-14
  20. S20 Spring Boot: Graceful Shutdown · Spring · 官方文档 · 核实于 2026-11-14
  21. S21 Java 25 Virtual Threads · Oracle · 官方文档 · 核实于 2026-11-13
  22. S22 Spring Boot: SpringApplication(含虚拟线程) · Spring · 官方文档 · 核实于 2026-11-13
  23. S23 Google Java Style Guide · Google · 官方文档 · 核实于 2026-11-13
  24. S24 Checkstyle 的 Google Java Style 配置 · Checkstyle · 官方文档 · 核实于 2026-11-13
  25. S25 Spotless Gradle 插件 · DiffPlug · 官方文档 · 核实于 2026-11-13
  26. S26 ktlint · Pinterest · 官方文档 · 核实于 2026-11-14
  27. S27 detekt · detekt · 官方文档 · 核实于 2026-11-14
  28. S28 Error Prone · Google · 官方文档 · 核实于 2026-11-14
  29. S29 SpotBugs · SpotBugs · 官方文档 · 核实于 2026-11-14
  30. S30 NullAway · Uber · 官方文档 · 核实于 2026-11-14
  31. S31 ArchUnit · TNG · 官方文档 · 核实于 2026-11-14
  32. S32 Spring Modulith · Spring · 官方文档 · 核实于 2026-11-14
  33. S33 JUnit 发布说明 · JUnit · 官方文档 · 2026-08-07 · 核实于 2026-11-13
  34. S34 AssertJ · AssertJ · 官方文档 · 核实于 2026-11-14
  35. S35 Testcontainers for Java · Testcontainers · 官方文档 · 核实于 2026-11-14
  36. S36 Spring Boot: Testcontainers · Spring · 官方文档 · 核实于 2026-11-13
  37. S37 Mockito · Mockito · 官方文档 · 核实于 2026-11-14
  38. S38 WireMock · WireMock · 官方文档 · 核实于 2026-11-14
  39. S39 SLF4J · QOS.ch · 官方文档 · 核实于 2026-11-14
  40. S40 Spring Boot: Logging(含结构化日志) · Spring · 官方文档 · 核实于 2026-11-14
  41. S41 Java 25 Serialization Filtering · Oracle · 官方文档 · 核实于 2026-11-14
  42. S42 find-sec-bugs · find-sec-bugs · 社区 · 核实于 2026-11-14
  43. S43 Spring Boot: Calling REST Services(RestClient) · Spring · 官方文档 · 核实于 2026-11-14
  44. S44 Spring Boot Migration Guide(含 ddl-auto 与迁移工具) · Spring · 官方文档 · 核实于 2026-11-13
  45. S45 openGauss JDBC 驱动类与环境类 · openGauss · 官方文档 · 核实于 2026-11-13
  46. S46 OWASP Dependency-Check · OWASP · 官方文档 · 核实于 2026-11-14
  47. S47 OSV-Scanner · Google · 官方文档 · 核实于 2026-11-14
  48. S48 CycloneDX Maven 插件 · CycloneDX · 官方文档 · 核实于 2026-11-14
  49. S49 japicmp · siom79 · 社区 · 核实于 2026-11-14
  50. S50 Kotlin binary-compatibility-validator(维护模式说明) · JetBrains · 官方文档 · 核实于 2026-11-14
  51. S51 Quarkus Releases · Quarkus · 官方文档 · 核实于 2026-11-13
  52. S52 Micronaut Release Announcements · Micronaut Foundation · 官方文档 · 核实于 2026-11-13
  53. S53 Ktor Releases · JetBrains · 官方文档 · 核实于 2026-11-13
  54. S54 Hibernate ORM relicensed under ASL 2.0 · Hibernate · 官方文档 · 2025-03-14 · 核实于 2026-11-14
  55. S55 jOOQ Licensing · Data Geekery · 官方文档 · 核实于 2026-11-14
  56. S56 HikariCP · brettwooldridge · 官方文档 · 核实于 2026-11-14
  57. S57 flyway/flyway(LICENSE) · Redgate · 官方文档 · 核实于 2026-11-14
  58. S58 The Flyway engine, OSS and Redgate · Redgate · 官方文档 · 核实于 2026-11-14
  59. S59 Liquibase Community for the future(FSL) · Liquibase · 官方文档 · 2025-09-30 · 核实于 2026-11-14
  60. S60 Resilience4j · Resilience4j · 官方文档 · 核实于 2026-11-14