分享

版本冲突时,如何在所有 jar 包文件中搜索冲突?

 万皇之皇 2018-01-26

问题 1: jenkins 打包失败了,导致我无法安装代码到测试环境,怎么办?

: 一般我们都会基于 jenkins 做一些二次开发,以适应公司内部的需求,或者优化一些修改化的东西。 但是由于 jenkins 本身还是比较复杂的,有时候难免我们搞不清楚其原理,从而导致一些无法打包的问题。 当然,我这边遇到的问题一般都是由于 jenkins 的缓存机制导致的问题,所以,在我本地可以打包的代码,放到 jenkins 上就死活打不了包,因为我依赖的一个 jar 包,由于被 jenkins 缓存了一个老版本的包,里面没有我新的东西从而导致打包失败,看起来短时间内无法解决这个缓存问题。

于是,我通过本地 ide 工具打好 war 包后,上传到服务器的 tomcat 目录,等待 tomcat 自动部署完成后就可以重新启动新代码了,从而绕过了 jenkins 失败的问题了。

针对 jar 包,则更为方便,直接本地生成 jar 包,然后替换服务器上的相应包,重启服务即可。

总之,这里的解决方案就是,当工具出了问题的时候,我们就不能再依赖工具了,回到原始状态解决问题。

问题 2: 当我们运行了代码(war/jar)后,报某个方法未找到,即:java.lang.NoSuchMethodError:, 仔细查看代码,其实是有该方法的,如何排查?

: 针对该问题,一般情况下都是由于引入了多个相同功能的 jar 包,且包路径完全一致,而在类加载器加载时,可能会加载到你不想要加载的类,从而导致没有该方法。

解决办法就是,删除不是自己的引用,从而达到使用自己意图的类。maven 中即表现为排除某个依赖,如:
b25afd7494e34eb988bfaf33cce59e69.png

但是,还有个问题,那就是如何才能找到是引用了哪个包,才导致的冲突呢?因为你从本地代码来看,没有一点异常。

我们可以直接搜索整个包的引用,并解开其中的代码,查看是冲突的类(冲突方法比较难找出来),当然是直接在服务器上进行查找了。

find . -name '*.jar' -exec jar -tvf {} \; | grep EE # 即找出所有的 jar 包,再解压出其文件列表,再搜索冲突的类名

如果有发现两个相同的结果,那么就是冲突了,解决该冲突即可。

当然,如果引入的 jar 文件不多,或者你有基本方向怀疑是哪个包冲突了,那么,直接将该包下载下来,用反编译工具(如 jd-gui)编译出来,查看其内部情况,便一目了然。

问题 3: 发现 tomcat 启动异常快,而且很多加载流程都没有,就直接启动了,实际上各个应有的服务都不存在,这怎么排查?

: 这种问题比较没有头绪,解决起来也基本靠运气。 这里 tomcat 看起来正常启动了,但是实际上很多事情都没做,没加载。从另一个角度来说,就是加载中断了。最麻烦的是日志中一点信息都不会给出。一般可以先从代码的改动处开始排查,以一段一段的代码还原方式为主要排查手段。

其中有一很关键的问题就是,你引用了一个 jdk 版本比你自己的运行环境高的 jar 包,按照 jvm 的加载原理,其会先检查 class 文件的版本号,如果高于自己所能加载的版本,那么,它就直接拒绝加载了,而并不会检查该 class 文件是否引用了一些不认识的特性。如果 jvm 不加载类了,那么你后续流程就无法进行了。

如果确实是因为 jar 包版本导致的问题,那么,问题就好解决了。 1. 要么叫给你提供 jar 包的同学将其打包的 jdk 版本降到你需要的版本就可以了。 2. 升级自己的 jvm 运行环境,升级 jdk, 当然这个风险可能会有,小心行事。

以上,就是一点点问题排查心得,聊以慰藉。也希望对有类似的问题的同学指明一个方向。

遇到问题的时候我们往往是这样,一个问题,可能几天下来也不一定能解决,但是到真正解决了的时候,发现其实很简单。然后,也许下一次,又继续!

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多