升级Jersey 2.26后反序列化出现NullPointerException求助
看起来你在升级Jersey版本后遇到了一个有点诡异的NPE——Eclipse里运行一切正常,但测试环境就抛出了Yasson相关的空指针,这大概率是Jersey默认集成的Yasson JSON-B实现和你在用的Genson发生了冲突导致的,毕竟Jersey 2.26开始默认把Yasson作为JSON-B的处理组件。下面给你几个具体的排查方向:
排除Yasson依赖,彻底避免冲突
Jersey 2.26的BOM可能自动引入了Yasson相关依赖,哪怕你没显式声明。你可以在pom.xml里排除掉Yasson及其关联的Jersey JSON-B组件,确保所有JSON处理都由Genson接管:<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <exclusions> <exclusion> <groupId>org.eclipse.yasson</groupId> <artifactId>yasson</artifactId> </exclusion> <exclusion> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-jsonb</artifactId> </exclusion> </exclusions> </dependency>也可以直接在Jersey BOM的依赖节点下做全局排除,根据你的项目依赖结构调整即可。
确保Genson Provider的优先级更高
有时候即使你手动注册了Genson,Jersey还是会优先使用默认的Yasson Provider。你可以给Genson的Feature设置更高的优先级,比如:// 数字越小优先级越高,确保Genson比Yasson先被调用 rc.register(new GensonJaxRSFeature().use(genson), 1);或者给
GensonJaxRSFeature类添加@Priority(Priorities.ENTITY_CODER)注解,强化它的优先级。排查测试环境的类加载差异
Eclipse和测试环境(比如Maven Surefire插件)的类加载顺序可能不一样,导致Yasson的类被意外加载。你可以在测试代码里打印当前注册的所有Provider,看看JSON相关的组件有哪些:for (Provider provider : rc.getProviders()) { System.out.println("已注册Provider: " + provider.getClass().getName()); }如果输出里出现Yasson的
JsonBindingProvider,说明它确实被注册了,需要进一步排查引入来源。调试Yasson NPE的根源
报错发生在DeserializerBuilder.isJsonValueEvent(DeserializerBuilder.java:155),这个方法里大概率是某个核心参数为null。你可以在测试环境里做这些操作:- 检查触发NPE的请求体是否为空,或者格式是否异常;
- 给Yasson的相关类加断点,看看
JsonBinding实例是否被正确初始化,是不是缺少配置导致内部对象未实例化。
验证Genson与Jersey 2.26的兼容性
可能你当前使用的Genson版本不兼容Jersey 2.26的新HK2依赖。建议升级Genson到最新稳定版(比如1.6+),在pom.xml里显式指定版本:<dependency> <groupId>com.owlike</groupId> <artifactId>genson</artifactId> <version>1.6</version> </dependency>显式禁用Jersey的默认JSON-B支持
在你的ResourceConfig里添加配置,强制Jersey不自动注册JSON-B相关的Provider:rc.property("jersey.config.jsonFeature.disableJsonB", true);这样就能彻底切断Yasson被自动加载的可能性。
内容的提问来源于stack exchange,提问作者Rob Audenaerde

