工作填坑记,因为idea打包导致没有加载真正的jar包的问题,引发关于JavaAgent双亲委派的理解(可能描述的不准确)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/dataiyangu/article/details/102642541

背景

ibmmq 的相关jar包maven仓库是没有的,用的8版本的进行测试agent,原来是没问题的,这次怎么也不行。

原来MQMessage类中是有getProperty这个方法的,可是竟然通过反射报错没有这个方法。
把当前依赖的ibmmq的先关jar包下载下来,查看源码发现确实有这个方法呀,我头然感到有点毛骨悚然,灵异事件?
无法相信,通过getDeclareMethods打出了所有的MQMessage类中的方法,确实没有这个方法,究竟是什么鬼?

分析

因为不是用的maven打包,需要通过idea打包,打包的方式是这样的。
在这里插入图片描述
如上图,箭头所指是真正的demo jar包,它所依赖的是当前的同级目录的其他jar包。
可是:
在JavaAgent中System.out.println("java.class.path"+System.getProperty("java.class.path"));,(这个属性的意思是类加载的路径,貌似是所有需要加载的类的路径,所以我粗略的理解为当前加载了哪些jar包。可能有些不准确)查看加载了哪些jar包,发现并没有加载ibmmq的 8版本
相关的jar包并没有加载本demo同级目录下的相关jar包。

在agent的中打印日志,得到MQMessage这个类所在的jar包

log.debug("msg jar ====== [%s]",msg.getClass().getProtectionDomain().getCodeSource());

最终打出的jar包是当前jdk的ext目录下咋ibmmq.jar,而不是我上面的目录中的jar。
然后把这个jar send到桌面,发现确实是没有这个方法。

至此,问题有了眉目了。
通过查看demo中的加载jar包的依赖MANIFEST.MF发现
在这里插入图片描述
如图

引发的思考

上面确定了问题,这里来分析一下~

为什么加载到了jdk 的 ext里面的jar

双亲委派机制得工作过程:
1-类加载器收到类加载的请求;
2-把这个请求委托给父加载器去完成,一直向上委托,直到启动类加载器;
3-启动器加载器检查能不能加载(使用findClass()方法),能就加载(结束);否则,抛出异常,通知子加载器进行加载。
4-重复步骤三;

在这里插入图片描述

针对于我的情况,可能就是因为ext中有了ibmmq需要的jar包,所以不去app层面找这个jar包了,即MANIFEST.MF。

解决方案

  1. 将ext下面ibmmq的jar删掉
  2. 换一个ext下面没有ibmmq的jar的机器。

(好吧,这两个解决方案好像是一个意思~)

猜你喜欢

转载自blog.csdn.net/dataiyangu/article/details/102642541