https://dalin.blog.csdn.net/article/details/112130831
对于不同groupid,同时打入war包,又存在相同全限定类名不同实现的类,有没有办法摸索它的加载顺序?
1 查看加载顺序
在 jvm 启动脚本中,添加 -verbose
参数或者 -XX:+TraceClassLoading
2
问题就是jar的加载顺序问题,而这个顺序实际上是由文件系统决定的,linux内部是用inode来指示文件的。
这种储存文件元信息的区域就叫做inode,中文译名为”索引节点”。每一个文件都有对应的inode,里面包含了与该文件有关的一些信息。
Unix/linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。
3
作者发现,通过多种测试场景,发现本地开发、测试环境都无法复现的问题,在 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++层有强关联影响的投机取巧的漏洞