冒烟测试核心是验证应用在新JVM上“启动、连通、响应、不崩”。必须检查字节码兼容性、模块路径行为变化、JVM参数兼容性、基础服务连通性,并通过启动确认、健康端点调用、最小闭环业务逻辑三步快速断言。

冒烟测试不是跑一遍 hello world
上线前用 OpenJDK 新版本(比如 JDK 17 升级到 21)做冒烟测试,核心不是验证 java -version 能否输出,而是确认你的应用在新 JVM 上能「启动、连通、响应、不崩」。很多团队卡在“编译通过就以为稳了”,结果上线后出现 UnsupportedClassVersionError、ClassNotFoundException(因模块系统变化)、或 GC 行为突变导致接口超时——这些都该在冒烟阶段暴露。
必须覆盖的四个关键检查点
冒烟测试要直击运行时契约,而不是只看构建流程:
-
字节码兼容性:确认所有 JAR 包(含第三方依赖)目标版本 ≤ 新 JDK 的支持上限。例如 JDK 21 默认不加载 class 文件版本 65+(对应 JDK 21 编译),但若你用了 JDK 22 编译的库,就会在
ClassLoader.defineClass阶段直接抛UnsupportedClassVersionError -
模块路径行为变化:JDK 9+ 引入模块系统,JDK 17 后默认启用
--illegal-access=deny。如果你的应用或依赖(如某些老版 Log4j、CGLIB)反射访问了sun.*或jdk.internal.*类,会在首次调用时失败,错误日志里会出现java.lang.reflect.InaccessibleObjectException -
JVM 参数兼容性:旧参数如
-XX:+UseParallelGC在 JDK 21 仍可用,但-XX:+UseConcMarkSweepGC已被移除;-Xloggc在 JDK 9+ 必须改用-Xlog:gc*,否则 JVM 启动失败 -
基础服务连通性:不只是应用能启动,还要验证它能否真正工作——连接本地 MySQL(驱动是否支持新 TLS 版本)、调通 Redis(Lettuce 是否兼容新 NIO 实现)、读取 classpath 下的
application.yml(Spring Boot 3.x 要求 JDK 17+,但 YAML 解析器可能因 JDK 内置 JAXB 移除而报错)
用最简方式快速验证(不依赖 CI)
本地或预发环境执行三步即可形成有效冒烟断言:
- 用新 JDK 启动应用,加
-XshowSettings:properties -version确认实际加载的java.home和java.version,避免 PATH 混淆 - curl
http://localhost:8080/actuator/health(Spring Boot)或自定义健康端点,HTTP 状态码 200 且 body 含"status":"UP"才算通过「可响应」 - 触发一个最小闭环业务逻辑:比如调用一次带数据库写入的 API(如 POST /users),再 GET 查回数据,比对字段值。这能同时验证 JDBC 驱动、连接池、事务传播、序列化(如 Jackson 对 record 类型处理)是否正常
别跳过数据库和网络环节——JDK 版本升级后最常出问题的,从来不是语法,而是 java.net.Socket 底层行为微调、SSLContext 默认算法变更、或 java.time 在时区解析上的严格度提升。











