博主是一个不是很聪明的码农。完美主义者,强迫症中期。这里会记录一些回忆和点滴,以博为镜。
武器库:
去年是忙碌的一年,今年陆续总结回顾下吧。
我目前所在的项目,使用了Mybatis做ORM,SQL是写到Mapper配置里,所以就导致一个问题,Mapper的语法无法在编译期被检查。而且Mapper错误在运行时的提醒非常晦涩,很难快速定位解决(比如resultType写成了resultMap,服务会不停的重新加载,直到OOM)。特别是开发比较紧张的时期,如果有人写了有问题的Mapper部署到开发服务器上,从发现到解决问题几个回合下来,浪费的不只是一个人的时间,被阻塞的有可能是整个研发团队。
我于是思考能否在发布前发现类似问题。翻了下资料,Mybaits没有相关检查的工具类,没办法,自己动手,丰衣足食。
细细想一下,首先是时机问题,编译期是不用考虑了,那么夹在编译期和运行时中间的只有一个构建期,我们项目用了我厂的omad发布系统,构建脚本是ant写的,想到这思路突然就有了:我在构建期启动一下看报不报错不就齐活了?
于是着手研究错误Mapper导致的异常栈,走读了相关Spring代码,发现第一个DAO方法的调用会触发所有Mapper文件的检查,那么事情就更简单了。
首先是修改构建脚本,在编译打包完成后主动调用一个main函数,启动一下Mybatis相关的部分:
|
|
这里failonerror设置为true ,把这个target放到整个打包的最后一步:
|
|
然后最核心的问题就是这个函数该怎么写:
|
|
如上,短小精悍,写一个Mapper检查专用的Spring配置,启动上下文后主动调用一次DAO访问,然后检查只要不是CannotGetJdbcConnectionException
,就认为必然出了问题,而且极大可能是Mapper的语法不正确。
这里之所以放过CannotGetJdbcConnectionException
是因为omad打包是在独立的打包机执行的,这机器必然没有我们数据库的访问权限,而且只有Mapper检查无误后才会执行真正的DAO操作,也就意味着,它能抛出CannotGetJdbcConnectionException
的话,Mapper的检查就是通过的。
最后看一下专用的Spring配置:
|
|
注意dataSource
的配置,参数的value部分随便填填就好了。
就是这么简单,我只修改了开发环境几个重要工程的打包脚本,添加了这步Mapper文件检查,其他环境也不需要浪费这个时间。后来这几段代码屡立战功,数次把错误的发布挡在运行之前。
前几日发现了ant的一个bug。我写的一个打包的ant脚本在我的mac上运行正常,但有同事在windows上则构建失败,我跑到我的windows上测试了下,居然也是失败的,定位了下问题,发现是<jar jarfile="path/to/a.jar"/>
在windows上并未创建相应的path/to二级目录。这是我从没遇到过的情况,我首先想到的是去linux上试了下,打包正常这说明并非我的系统环境有多特殊,于是作为一个MacOS用户,一个诡异的想法便开始形成:我觉得这可能是ant在windows上的bug。
然后我去apache下载了最新的ant源码,Jar继承了Zip类,扫了一眼相关源码,看到一段:
|
|
我更疑惑了,看起来ant已经考虑到jar所在的目录的创建了啊。
于是我跑到windows里,准备调试一下相关逻辑,在eclipse里配置了调试环境,把我那个ant脚本作为参数,在开始debug前,我先运行了一下,居然成功了。越来越疑惑了。
仔细想了下,我决定把我windows上老的ANT_HOME
切换到最新版的ant,然后事情开始明朗了,构建成功了。我终于恍然大悟,可能是因为一直忽略了ant的版本差异,导致浪费这么多精力。我用的是1.7.0版的ant构建出错,但查阅的却是1.9.2版的,难道新版已经修复了这个bug?为了证实这个猜测,我去ant的subversion仓库里,拉取了Zip.java近期的log,终于发现了REV:807960的log:
create parent directory of archive in
and if needed. PR 45377. Based on patch by Remie Bolte
果不其然啊!可惜失去一个为开源社区贡献代码的机会。