上海疫情扩大之前,组里有个交易导出的需求,主要是会一次性导出几百万上千万的数据。之前都是直接生成csv格式的,这次运营突然不接受了,必须要excel的。这个开始还没怎么重视,不就是换种格式吗?也没什么大不了的,不就是两天时间的问题。

组里兄弟哼哧哼哧干了两天,晨会的时候抛出一个问题。我写的代码在本地电脑上都是可以正常的生成xlsx文件,但是到了测试环境就不行了。系统一直卡在那里,死死的就是不动。当时也没在意,让他不行就继续csv吧,大不了后续给运营搞一个本地的csv转excel的工具。反正windows下是正常的,也不是什么大问题。奈何领导不同意,没办法只能硬啃这个问题。

上去先看了下兄弟的改动,也没什么大坑。也都是复制粘贴了下以前的代码,然后加上自己的逻辑,至少看起来没啥大问题。远程了下测试环境,触发了下相关操作,果然如大兄弟所说的那样,本地测试毫无问题,测试环境是泥牛入海,操作完之后,啥日志也没有。

没有日志倒也没啥大问题,弄了个线程日志看看。非常奇怪的卡死在了POI对象初始化的时候。问题是这行代码在其他地方也是照常使用,理论上不会有啥问题。最终的堆栈卡在了类加载的地方,也就是loadClass的地方。这就更奇怪了,死锁也不应该在这个地方了,类加载线程无关啊。

线程日志

问题就在这里卡住了。后面各种查资料,或者想法绕开POI,最终发现都是不行。既然不能取巧,就只能继续硬啃下去了。正好领导在第二天晨会上提了一句,是不是又是jboss类加载的问题。脑袋里突然想到,本地电脑可以,而测试环境不行,可能并不在于操作系统,而是本地环境用的jetty容器,而测试环境用的是jboss容器,两者最大的不同,就是jboss容器中多出了一大堆的默认jar包。

然后就开始翻jboss环境自带的jar与我们项目中打包的jar,发现poi强依赖的xmlbeans的包在jboss和我们项目的lib目录下同时存在,虽然版本一样,但是同时存在可能导致问题。于是就把项目中的xmlbeas在打包的时候给排除掉,重新上测试环境,问题圆满的解决了,猜测可能是两个jar同时加载导致死锁卡住。

整个问题解决过程耗时两天,这种类似问题会越来越少,毕竟后面这种自带jar的web容器已经越来越没有市场。耗时长的一个因素就是在排查jboss包自带包时有所遗漏,导致中间有很大一部分时间在错误地方排查。还有就是总想取巧,想这种老问题,总是想能避开就避开,不想深入研究。但解决问题的唯一办法还是直面应对,这才是最有效的方法。