一次maven构建类冲突解决方法论(二)加载顺序

https://dalin.blog.csdn.net/article/details/112130831

 

对于不同groupid,同时打入war包,又存在相同全限定类名不同实现的类,有没有办法摸索它的加载顺序?

 

 1 查看加载顺序

在 jvm 启动脚本中,添加 -verbose 参数或者 -XX:+TraceClassLoading

 

问题就是jar的加载顺序问题,而这个顺序实际上是由文件系统决定的,linux内部是用inode来指示文件的

这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。

Unix/linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。

 

作者发现,通过多种测试场景,发现本地开发、测试环境都无法复现的问题,在 uat 环境下,只要这两个包同时存在,都会启动报错

最后在官方文档发现这个:

The order in which the JAR files in a directory are enumerated in the expanded class path is not specified and may vary from platform to platform and even from moment to moment on the same machine. A well-constructed application should not depend upon any particular order. If a specific order is required, then the JAR files can be enumerated explicitly in the class path.

大意为:同一个目录下,jvm加载jar包顺序是无法保证的,每个系统的都不一样,甚至同一个系统不同的时刻加载都不一样。

于是乎,我也不纠结某台服务器上的类加载顺序,在开发阶段就先将这个包冲突的情况,给提前解决掉~

 

4 在去除log4j时碰到war中有3个org.apache.log4j.Logger

存在于:

log4j

log4j-extras

com.documen.log4j

要加上且希望优先加载 log4j-1.2-xxx.jar中的org.apache.log4j.Logger,且希望不去除第3个com.documen.log4j的jar包,因为后果未知

起先4个服务器环境,log4j都打出日志了,太巧了;有没有可能出现并利用下面的情况

需要的类CS在jarA中,还有个同名类在jarB中,

先加载jarA独有的CSB类,让jarA先进来,然后再加载CS,优先加载jarA的CS,这样既不用exclusionjarB,避免风险,又能将log4j嫁接到log4j2

(干掉log4j,log4j-extras,保留com.documen.log4j,加入log4j-1.2-xxx,用上述方法让log4j-1.2-xxx的Logger类优先加载)

 

但是,这种方案很难证明,即使我本地验证通过,也不能证明在所有环境中100%应验,而且,本身也不应该去证明、挖掘这种跟系统、jdk、jvm c++层有强关联影响的投机取巧的漏洞

posted on 2021-02-04 13:35  silyvin  阅读(492)  评论(0编辑  收藏  举报