标题canal监听器发送activeMQ消息失败原因分析
1、没有打印更详细的错误信息,只是打印出一句:2020-07-23 09:25:05.201 ERROR 15936 --- [pool-2-thread-1] .s.c.c.a.AbstractBasicMessageTransponder : pool-2-thread-1: 委托 canal 监听器发生错误!
错误信息太少,不利于分析。
因为代码中是将异常抛出,并没有打印异常栈信息
2、打印出的错误信息从上到下越来越具体,越来越接近本质错误
3、NoClassDefFoundError org.apache.zookeeper.Watcher
这种NoClassDefFoundError错误一般来说不是jar包损坏就是jar冲突。
此次而言,zookeeper-${version}.jar在项目中有两个版本3.4.5和3.4.6,因为jvm在加载的过程中,项目的加载的顺序问题。同一个类(全限定名相同)在jvm中只会加载一次。在编译时,我们用到了3.4.6里面的某个类,但是这个类在3.4.5中不存在;而在运行时当加载了3.4.5版本后,就不会再加载3.4.6版本,此时就会产生NoClassDefFoundError
4、什么是jar冲突,JAR包冲突的原理
案例:A -> B -> C -> D2 , E -> F -> D1
我们服务引入A、E两个依赖,按照maven默认的依赖管理,D2版本的jar包不被引入,引入的是D1版本。而我们知道jar包升级是由于我们加入了一些特性,可能表现为类的增加或方法的增加。那么C中可能使用到了D2引入的新类或方法。当我们程序使用了C对应的功能时,JVM去加载Class会发现D1版本并没有这个类,就会并抛出ClassNotFoundException。 当调用D2新增的方法,由于D1类中并没有这个方法,就会抛出NoSuchMethodError。
在进行软件设计时,一般都要考虑向后兼容,不会删除或修改以前版本的API,除非是大的版本升级。如果不遵循以上设计原则的话,那么只要是引用了不同版本jar包就要考虑冲突的可能。
5、解决方法
如果想查看这个冲突的class类在哪个冲突的文件jar包中,在冲突的类上使用ctr+shift+t进行查询包所在的位置。
例如:
Maven中jar包冲突的解决方式:https://www.cnblogs.com/jichi/p/11627487.html