1. 背景介绍
前天公司一个前辈交过来一个项目,项目几个月之前已经做完了,甲方一直没有上线,后来负责开发以及项目管理的小伙伴都调走了,最近项目要重启启动,我负责后续的跟进。
接手项目过程是前辈给介绍了两个多小时,七八个模块,三十个左右菜单,林林总总讲了2个多小时下来,初步对项目的业务有了一点了解,大部分细节还是蒙圈状态。
2. 问题初现
百般无奈之下,只能发挥咱的强项了,撸代码。
第一步先把项目跑起来,跟同事要了项目代码的git地址,下载到本地。
代码有了,进入第二步,工程导入到环境中,我这里环境用的idea,版本201803。
正在进度一路顺风顺着、沾沾自喜的时候,问题来了,源代码竟然报错。
错误提示如下:
Error:(35, 34) java: 找不到符号
符号: 方法 setFunctions(java.util.Map<java.lang.String,java.lang.Object>)
位置: 类 org.apache.commons.jexl3.JexlEngine
第一反映是之前的小伙伴是不是有什么代码没传啊?问下之前来交接的前辈,前辈说他之前不负责代码,但是代码应该是没问题的,之前都可以正常运行。
好吧,还是仔细看下代码吧。报错代码如下图:
3. 问题分析
报错的代码是一个第三方控件,报错代码可以理解为JexlExpressionEvaluator.getJexlEngine().setFunctions(functions),其中getJexlEngine返回的是一个org.apache.commons.jexl3.JexlEngine,看了下源码,这个类中就没有setFunctions方法,怎么可能不报错呢?但是前辈说之前代码是没有问题的,根据以往的经验,这种问题多半是jar包冲产生的。
根据这个思路,先来看下,报错的插件的jar包依赖关系,如下图:
项目直接引入的控件是jxls-poi,版本是1.0.15,jxls-poi使用了jxls,jxls又使用了commons-jexl3。报错的类就是属于jar包commons-jexl3的,全局搜索了一下,没有发现别的jar包中相同路径同名的类,貌似问题跟jar又没关系了。
问题查到这,没有思路了,上法宝,度娘粉墨登场。
别说,度娘还是很有货的,看下图,代码基本是一摸一样的,人家也是好用的,侧面印证前辈的说法,这个代码之前的是好用的。
代码没问题,过了几个月就不好用了,那么变化的只能是环境,我的项目是使用maven对项目进行管理的,所以根本上说还是jar包出了问题。期间一个偶尔的发现让我有新的思路,网上的例子里边用的jxls版本是2.4.0,回去看了下我项目的jxls,版本是2.6.0,会不会是这块的问题呢?为了验证,去mave工厂中下载了2.4版本的jxls控件的jar包,对比了一下里边的pom文件,果然有重大发现:
2.4版本pom
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
<version>2.1.1</version>
</dependency>
2.6版本pom
<properties>
<spockVersion>1.0-groovy-2.4</spockVersion>
<jexl.version>3.1</jexl.version>
</properties>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl3</artifactId>
<version>${jexl.version}</version>
</dependency>
差了一个大版本号啊,报错的方法正好是这个第三方控件在做大版本升级改掉的,报错就不稀奇了。这里尤其需要注意的一个地方是jxls-poi在引用jxls的时候使用了版本向上支持的的写法,代码如下:
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>[2.4.5,)</version>
</dependency>
这种写法的意思是可以使用2.4.5以上的所有版本都可以,而jxls的2.4.*版本是在2018年发布的,2.5以及2.6是2019年5月份之后才发布的,如下图:
这样也解释了为什么前辈们的代码都是好用的,而到我这里却不好用了,至此问题所有的环节都可以解释的通了,问题明确定位为jar版本升级引起的bug。
4. 问题解决
根据时间推测,前辈们应该用的是jxls的2.4.7版本,手动引入此jar包,问题解决。代码如下
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>2.4.7</version>
</dependency>
5. 问题反思
解决今天这个问题整整浪费两个多小时时间,其实问题并复杂,只是引起问题的原因不常规,不容易定位。jxls-poi控件在引入jxls的时候使用的版本向上兼容的写法明显是不合适的,这也是我们在项目管理的时候需要注意的地方。