从WebSphere迁移到Open Liberty时出现序列化错误求助
排查思路与解决方案
核心异常分析
从堆栈信息来看,Jackson在序列化Information.dataGroup这个ArrayList时,错误地用IntegerSerializer处理Image对象,导致类型转换失败。这说明Jackson对该列表的元素类型推断出现偏差,根源大概率和类加载、类型声明或Jackson配置有关。
具体排查步骤
1. 确认Jackson的实际加载版本
虽然你指定应用使用Jackson 2.11,但Open Liberty的类加载策略或依赖特性可能引入了其他版本的Jackson:
- 启动应用时添加JVM参数:
-verbose:class,搜索com.fasterxml.jackson.databind.ObjectMapper和NumberSerializers$IntegerSerializer的加载路径,确认是否来自应用的WEB-INF/lib。 - 使用Open Liberty的
dump功能(执行server dump <serverName>),查看类加载器报告,检查Jackson类的来源。
2. 调整类加载器策略
WAS默认是父类优先,而Open Liberty默认是应用优先(Parent Last),这是关键差异:
- 如果你的应用依赖了Open Liberty提供的MicroProfile特性(如
mp-rest-client、mp-jwt),这些特性可能自带Jackson版本,和应用的2.11冲突。 - 解决:在
server.xml的<webApplication>标签中强制设置应用优先加载:<webApplication id="your-app" location="your-app.war" name="your-app"> <classloader delegation="parentLast"/> </webApplication>
3. 检查实体类的泛型声明
如果Information类中的dataGroup字段是原始类型(未指定泛型),Jackson可能无法正确推断元素类型:
- 检查字段声明:如果是
private ArrayList dataGroup;,改为private ArrayList<Image> dataGroup;,或使用List<Image>代替原始ArrayList。 - 检查是否有
@JsonSerialize或@JsonDeserialize注解错误指定了序列化器,比如给dataGroup指定了Integer相关的序列化器。
4. 清理Servlet API依赖
Open Liberty自带符合规范的Servlet API,应用无需打包该依赖:
- 检查应用的依赖配置(如Maven/Gradle),确保Servlet API的scope设为
provided:<!-- Maven示例 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> - 检查
WEB-INF/lib下是否存在servlet-api.jar或javax.servlet.jar,如果有则删除。
5. 验证列表元素的实际类型
排查是否存在代码逻辑错误导致dataGroup列表混入非Image对象:
- 在序列化前添加日志,打印
dataGroup中每个元素的类型:System.out.println("dataGroup元素类型:"); for (Object obj : information.getDataGroup()) { System.out.println(obj.getClass().getName()); } - 确认所有元素都是
com.test.apps.models.Image类型,排除反射或其他逻辑意外插入Integer的情况。
针对你猜想的补充说明
- Servlet jar差异:Open Liberty的Servlet API由服务器提供,应用无需打包。如果应用自行打包了Servlet jar,会引发类加载冲突,间接影响Spring和Jackson的协作,必须清理。
- Jackson版本冲突:虽然Jackson 1.x和2.x包名不同,但如果Open Liberty通过特性引入了Jackson 2.x的其他版本,类加载顺序的变化会导致应用加载服务器的Jackson而非自带的2.11,通过调整类加载策略可解决。
内容的提问来源于stack exchange,提问作者Mr Smith
相关产品推荐
相关产品推荐

