fastjson 1.2.84 能在 JDK 7 上跑吗?实测:编译能过,一启动就 UnsupportedClassVersionError

最近后台看到有人搜「fastjson1.2.84能在jdk1.7环境运行吗」。我拿一台 JDK 7 实际跑了一遍。

先说结论

  • JDK 8 及以上:没影响。 同一段代码在 JDK 8 上跑 1.2.83 和 1.2.84 都正常。
  • JDK 7:1.2.84 起不来。 javac 只给 5 条警告、退出码是 0,所以构建不会失败 ;程序一运行就抛 UnsupportedClassVersionError。
  • 原因 :1.2.84 的 274 个 class 全是 Java 8 字节码(major 52),1.2.83 是 Java 5(major 49)。pom 里写的仍是 1.5,发布说明中英文两段都没提 JDK 要求。
  • 顺带一个坑 :1.2.84 里的 JSON.VERSION 常量还是 "1.2.83"。
  • JDK 7 上还想处理 CVE-2026-16723 :官方公告给的另外两个 P0 处置(开 SafeMode、换 1.2.83_noneautotype)都是 Java 5 字节码,在 JDK 7 上实测能加载,开关也生效。

实测:同一台 JDK 7,1.2.83 和 1.2.84

环境:Zulu 7.56.0.11(openjdk version "1.7.0_352"),Windows x64。jar 直接从 Maven Central 下载,SHA1 与 Central 上的 .sha1 一致:

版本 SHA1
1.2.83 9ee94951bc107d382519975d04bc950b6c6ab297
1.2.83_noneautotype 72fec75f60694cae71dbc169217a701d72b48df6
1.2.84 05773609a8ce27cc9cbfbec0009e02b1a7b83dde

测试代码只有一次最普通的解析:

java 复制代码
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class Demo {
    public static void main(String[] args) {
        JSONObject o = JSON.parseObject("{\"name\":\"tom\",\"age\":18}");
        System.out.println("fastjson " + JSON.VERSION + " -> " + o.getString("name") + "," + o.getIntValue("age"));
    }
}

1.2.83:编译、运行都正常,退出码 0。

复制代码
fastjson 1.2.83 -> tom,18

1.2.84 编译 :5 条警告,退出码 0 ,Demo.class 照常生成。

复制代码
warning: dl\fastjson-1.2.84.jar(com/alibaba/fastjson/JSON.class): major version 52 is newer than 51, the highest major version supported by this compiler.
  It is recommended that the compiler be upgraded.
...
5 warnings

另外 4 条警告内容相同,分别指向 JSONObject / TypeReference / JSONStreamAware / JSONAware。

1.2.84 运行:退出码 1。

复制代码
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/alibaba/fastjson/JSON : Unsupported major.minor version 52.0
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:808)
	...
	at Demo.main(Demo.java:5)

最要注意的是「编译只是警告」:用 JDK 7 编译,构建是绿的;问题要到启动或第一次用到 fastjson 时才出来。

对照:JDK 8(Zulu 8.96.0.205,1.8.0_504) :同一个 Demo.class(JDK 7 编出来的)配 1.2.83、1.2.84,都正常输出,退出码 0。

为什么:274 个 class 全是 major 52

逐个读三个 jar 里每个 class 文件的版本号,再看 MANIFEST:

版本 class 数 class 版本 MANIFEST Build-Jdk
1.2.83 274 全部 49(Java 5) 1.8.0_332
1.2.83_noneautotype 273 全部 49(Java 5) 1.8.0_332
1.2.84 274 全部 52(Java 8) 11.0.31

自己的项目想确认,一条命令就行(JDK 8 自带的 javap):

bash 复制代码
javap -v -cp fastjson-1.2.84.jar com.alibaba.fastjson.JSON | grep major
复制代码
  major version: 52

换成 1.2.83 的 jar,输出是 major version: 49。

pom 写的是 1.5,出来的为什么是 52

fastjson 仓库 1.2.84 这个 tag 下的 pom.xml,第 21 行还是:

xml 复制代码
<jdk.version>1.5</jdk.version>

maven-compiler-plugin 的 source / target 都引用它。1.2.83 那个 tag 也一样。

我用 JDK 11.0.31(和 MANIFEST 里记的同一个版本)把 tag 原样构建了一次:

复制代码
[ERROR] Source option 5 is no longer supported. Use 6 or later.
[ERROR] Target option 1.5 is no longer supported. Use 1.6 or later.

按仓库里的 pom 原样构建是编不过的。 再加一个参数 -Djdk.version=1.8 重新构建,编出来的 274 个 class 和 Central 上 1.2.84 jar 里的逐字节一致。

所以能确定的是:发布的 jar 和「JDK 11 + target 1.8」的构建结果一模一样。官方实际是怎么操作的、是不是有意不再支持 JDK 7,公开材料里没写。1.2.84 的发布说明中英文两段我都读完了,讲的是 4 条安全修复和 Maven 坐标,没有一个字提 JDK 版本。

顺带一个坑:JSON.VERSION 还是 "1.2.83"

上面 Demo 用 1.2.84 在 JDK 8 上跑,打印的是:

复制代码
fastjson 1.2.83 -> tom,18

不是我拿错了包,是 1.2.84 里的常量本来就是这个值:

bash 复制代码
javap -constants -cp fastjson-1.2.84.jar com.alibaba.fastjson.JSON | grep VERSION
复制代码
  public static final java.lang.String VERSION = "1.2.83";

如果你们的启动日志、健康检查或者自查脚本是靠 JSON.VERSION 判断「升没升」,升完 1.2.84 它还会告诉你是 1.2.83。要看真实版本,读 jar 里的 pom.properties:

bash 复制代码
unzip -p fastjson-1.2.84.jar META-INF/maven/com.alibaba/fastjson/pom.properties
复制代码
#Generated by Maven
#Wed Jul 29 15:23:45 CST 2026
groupId=com.alibaba
artifactId=fastjson
version=1.2.84

还在 JDK 7 上:CVE-2026-16723 怎么办

先看官方公告(fastjson2 wiki 安全公告)。它给的三个 P0 处置是「或」的关系:

官方 P0 处置 公告原文怎么说它 JDK 7 上实测
升级到 1.2.84 修复此漏洞 ❌ 加载即 UnsupportedClassVersionError
或启用 SafeMode 在漏洞触发路径之前即拒绝所有 @type ✅ 1.2.83 + SafeMode 能跑,开关生效
或切换 noneautotype 版本 漏洞相关代码在编译期被移除 ✅ 1.2.83_noneautotype 能跑

截至 2026-10-14,Maven Central 上 1.x 只有 1.2.83、1.2.83_noneautotype、1.2.84 三个版本。1.x 里带这次修复的只有 1.2.84,而它要 JDK 8。

JDK 7 上实测用的代码,比 Demo 多一行带 @type 的解析:

java 复制代码
Object o = JSON.parse("{\"@type\":\"Demo2$Bean\",\"name\":\"tom\"}");

三种情况的输出(都是 JDK 7u352,退出码都是 0):

复制代码
== 1.2.83 默认
plain  -> tom
@type  -> JSONException: autoType is not support. Demo2$Bean

== 1.2.83 + -Dfastjson.parser.safeMode=true
plain  -> tom
@type  -> JSONException: safeMode not support autoType : Demo2$Bean

== 1.2.83_noneautotype
plain  -> tom
@type  -> JSONException: safeMode not support autoType : Demo2$Bean

普通解析照常,带 @type 的报错从「autoType is not support」变成了「safeMode not support autoType」,说明 SafeMode 在 JDK 7 上确实开起来了。noneautotype 包不用加参数,行为和开了 SafeMode 一样。

两点要说清楚:

  1. 这两种处置都会全局关掉 AutoType 。业务里有靠 @type 还原子类的地方,开了会失败,先在测试环境验证。SafeMode 怎么开、哪些做法没用,我在 升不了 fastjson 1.2.84 时的缓解办法 里写过。
  2. 1.2.83_noneautotype 是 2022-06 发的 ,1.2.84 新加的那几处检查(比如 hasIllegalTypeNameChars)它里面没有。官方对它的说法是「漏洞相关代码在编译期被移除」。另外,官方公告列出的漏洞验证环境是 JDK 8 / 11 / 17 / 21。

长期来看,还是要把 JDK 升到 8,才能用上 1.2.84。

自查

几个项目一起查、或者 fastjson 被打进了 Spring Boot fat jar 里,可以用我写的零依赖小工具 fastjson-check。它读的是 pom.properties,不受 JSON.VERSION 的影响:

复制代码
[OK] fastjson 1.2.84
  版本来源:pom.properties
  结论  :fastjson 1.2.84 已包含 CVE-2026-16723 的官方修复(1.2.84 起)

v0.3.2 起,扫到 1.2.68~1.2.83 时给的「升 1.2.84」建议,会附上「需要 JDK 8 及以上」这个前提。

1.2.84 和 1.2.83 在漏洞修复上具体差在哪,看这篇:fastjson 1.2.49 中了 CVE-2026-16723 吗?1.2.84 和 1.2.83 到底差在哪。

数据来源(均为 2026-10-14 读取 / 实跑)

相关推荐
java_nnnn1 小时前
Spring Web MVC 入门:从一个 URL 到 Java 后端完整处理请求
java·前端·spring boot·spring
G018_star sky♬1 小时前
为什么java新建一个对象,需要obj o = new obj()这种写法
java·开发语言
高频因子挖掘机1 小时前
股票 API 返回 HTTP 429 怎么办?Python 量化系统的限流排查与重试设计
后端·github·api
mldong1 小时前
为了 token 自由,我把 jeeflow 工作流引擎用 MoonBit 写了一遍
后端·架构
高频因子挖掘机2 小时前
从回测到实盘:量化策略为什么不应该直接依赖行情 API
后端·github·api
驭渊的小故事4 小时前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
哦虎!9 小时前
【JavaEE】网络初识
java
for_ever_love__9 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
大鸡腿同学10 小时前
手心向上,手心向下
后端