项目场景:
在一个线上业务中,涉及到excel转pdf的相关操作,使用了poi库,但是一次运维中发现该功能产生了错误的结果,生成的pdf文件为空。报错信息为Caused by: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.CellStyle
问题描述
排查日志后发现报错信息为Caused by: java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.CellStyl
排查一:版本错误
排查依赖后发现该功能属于公共模块,公共模块下依赖了poi的3.1.5版本,确实没有该方法,因此需要升级为3.1.7
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
排查二:依赖冲突
完成版本升级后,重启服务报错依旧,猜测版本会有问题,因此打开lib发现有3.1.7和4.1.2两个版本
下图为改正后的两个版本依赖,原错误为图中4.1.0是3.1.7
继续查dependencies,发现在业务模块的pom中也引入了poi
将业务模块中的引入进行注释,程序仅使用公共模块的poi引入
排查三:版本错误
使用3.1.7版本后不报原错误,但是出现了ClassNotFoundException: org.apache.poi.ss.usermodel.WorkbookFactory的报错,翻了一下源码,发现3.1.7中是没有WorkbookFactory的,因此将公共模块中的3.1.7升级为4.1.2
排查四:版本兼容
在升级为4.1.2后,编译报错org.apache.poi.ss.usermodel.VerticalAlignment无法转换为short
定位发现原来是4.1.2相比较3.1.7部分API接口参数发生了变化
在原代码的基础上获得的HA对象进行getCode解决兼容性问题
同时原业务代码还进行了枚举判断单元格类型,也产生了兼容性问题
翻看了源码之后发现3.15 beta 3 之后的CellType源码有过更改
因此按照更改过后的进行相应业务代码的调整
排查五:easypoi引入的poi
完成上述操作之后发现依旧报错,继续排查,在lib中找不到其他的版本,遂查看pom依赖,发现引入了easypoi3.3.0,点进入查看后发现3.3.0的easypoi中引入了3.1.5的poi
查文档发现目前的easypoi好像仅支持到4.1.1的poi,在此处我升级到了4.1.2,这个版本引入的poi为4.1.0
排查六:easyexcel的poi引入
运行依旧报错。。。再查又看到一个easyexcel:2.2.0-beta1,发现里面也引入了一个
遂查文档,将easyexcel升级为3.0.5,此时内部引入的poi为4.1.2
总结
完成上述排查后,终于完成了该功能的修复,虽然问题解决了,但是程序引入了poi的4.1.0和4.1.2两个版本,并且引入了easypoi和easyexcel两个针对poi的封装工具类,显得非常冗余(因为之前代码不是我写的,轻易先不动业务代码),且虽然程序可以正常运行,但是poi小版本的冲突依旧在。因为easypoi至今未支持4.1.2的poi(仅支持到4.1.1),因此当下的方案为:easyexcel降级至依赖poi4.1.1的版本。