记一次诡异的 Cannot find declaration to go to,
Cannot resolve method 'getOnExpressions' in 'Join'
对于项目中通常问题,清除缓存,重启idea,或者仔细检查语法通常都能解决问题,但是这次却失效了,以下是原因及解决方案。
项目中使用了mybatisplus的多租户拦截器,但是在拦截sql的时候却报jsqlparse解析错误,而且仅仅是部分sql报错,并非全部sql报错,很容易让人怀疑是自己业务方法有问题,检查无法找到问题,一度怀疑sql解析器不够强大,不支持自定义的特殊sql,但是项目sql又是简单的join连接并且仅仅取了个别名,解析器难道如此拉胯?当然后来阅读sql解析器源码发现其功能异常强大,这是后话;
点击进去mybatis-plus的多租户源码中,发现调用jsqlparser的一行报错,仔细检查业务,并未发现问题,
点进去报错的jsqlr源码中发现该行提示 Cannot find declaration to go to,
Cannot resolve method 'getOnExpressions' in 'Join',非常奇怪源码中怎么会有这样的提示?
这里是mybatis-plus的多租户源码,怎么会提示找不到jsqlparser呢?但是点进去调用的类中明明能够看到调用的方法却找不到,
可以看到源码中这两行是标红的,但是点进去join后明明却又可以看到getOnExpression()方法
细心的你可能会发现少了个s,
于是清除缓存,重启idea,仍旧无济于事;
后猜想可能是jsqlparse不够强大,不支持自定义sql,但是debug后发现jsqlparse超乎想象的强大;
最后猜想可能是jar包冲突,而实际原因也确实是jar冲突,以下是排查思路:
1)找到join所在jar包,同时找到TenantLineInnerInterceptor所在jar包,发现如下两个:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.0</version></dependency>
于是猜想通常官方starter会做版本仲裁,可能该starter中已经包含了jsqlparser的jar包了,于是点进去果然发现了4.3版本的jar包,但是项目中却又引入了4.0版本的,所以果断将4.0的删除,发现原来提示Cannot find declaration to go to,
Cannot resolve method 'getOnExpressions' in 'Join' 的地方已经恢复了正常;
2)对于项目中其它引用4.0的代码切换为4.3的,并且重写部分报错的业务,至此完美解决;从这里也能看到是因为版本差异导致的
后记:对于项目中其它所有有版本冲突的地方,都可以采用此方法来进行仲裁排除;
适当阅读源码,debug源码,受益匪浅。