Skip to content

神策 Java SDK 与 Jackson 2.20+ 不兼容问题报告 #33

Description

@defia

一、摘要

神策 Java SDK(com.sensorsdata.analytics.javasdk:SensorsAnalyticsSDK)在 Jackson 2.20.0 及以上版本运行时,初始化阶段抛出 java.lang.NoSuchFieldError: SNAKE_CASE,导致 SDK 无法实例化;若 SDK 作为 Spring Bean 注册,会直接阻断宿主应用启动。该问题在 SDK 3.4.3 至最新 3.6.10 版本均存在,SDK 侧未做适配。

二、影响版本

组件 | 版本 -- | -- SensorsAnalyticsSDK | 3.4.3 ~ 3.6.10(当前最新,问题一直未修) jackson-databind | ≥ 2.20.0 运行环境 | JDK 17、Spring Boot 3.5.x

三、复现

最小复现代码:

ISensorsAnalytics sa = new SensorsAnalytics(
    new FastBatchConsumer(url, true, 50, 6000, 15, 15, failedData -> { ... }));

异常栈:

java.lang.NoSuchFieldError: SNAKE_CASE
    at com.sensorsdata.analytics.javasdk.util.SensorsAnalyticsUtil.getJsonObjectMapper(SensorsAnalyticsUtil.java:62)
    at com.sensorsdata.analytics.javasdk.consumer.FastBatchConsumer.<init>(FastBatchConsumer.java:68)
    at com.yimlink.ymcloud.common.config.SensorsConfig.init(SensorsConfig.java:51)
    ...

BatchConsumer 等其它 consumer 同样会触发,因为它们内部都调用了 SensorsAnalyticsUtil.getJsonObjectMapper()

四、根因分析

SensorsAnalyticsUtil.getJsonObjectMapper()(SensorsAnalyticsUtil.java:62)直接引用了 Jackson 的 PropertyNamingStrategy.SNAKE_CASE静态字段:

public static ObjectMapper getJsonObjectMapper() {
    ObjectMapper jsonObjectMapper = new ObjectMapper();
    jsonObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // ↓↓↓ 问题代码:引用了 Jackson 2.20 已移除的静态字段 ↓↓↓
    jsonObjectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    ...
}

该静态字段自 Jackson 2.12  @Deprecated,并在 Jackson 2.20.0 被移除。jackson-databind 2.20 的 PropertyNamingStrategy.java 注释明确写道:

NOTE! Since 2.12 up until 2.19, sub-classes defined here (as well as static singleton instances thereof) were deprecated due to databind#2715. They were removed in 2.20. Please use constants and classes in PropertyNamingStrategies instead.

Jackson 官方的迁移方案是改用 com.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE(注意类名多一个 s)。

因此 SDK 在 Jackson ≥ 2.20 的运行时上,访问 PropertyNamingStrategy.SNAKE_CASE 时找不到该字段,抛 NoSuchFieldError

五、影响

  • SDK 无法初始化,埋点数据完全无法上报

  • 若 SDK 实例化为 Spring Bean(企业集成中最常见的用法),会抛 BeanCreationException,直接导致宿主应用启动失败

六、期望的修复

建议在 SensorsAnalyticsUtil.getJsonObjectMapper() 中改用新 API,并对低版本 Jackson 做兼容:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
    // Jackson 2.12+
    mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
} catch (NoClassDefFoundError ignored) {
    // Jackson < 2.12 回退
    mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
}

或直接使用 PropertyNamingStrategies.SNAKE_CASE(放弃对 Jackson < 2.12 的支持,目前也几乎不存在此类旧环境)。

七、临时规避

 jackson-databind 锁定到 2.18.x(本方采用 2.18.8):

  • 2.18.x < 2.20,仍保留 PropertyNamingStrategy.SNAKE_CASE → 神策 SDK 可正常工作;

  • 2.18.8 已通过 Jackson LTS 回移修复 CVE-2026-54512 / CVE-2026-54513(NVD 明确该 CVE 修复版本为 2.18.8 / 2.21.4 / 3.1.4);

  • 2.18.x 同时是 Spring Boot 3.5.x 的原生 Jackson 版本线,兼容性最佳。

八、参考链接

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions