classloader getresource jar包资源冲突情况,父亲为大,兄弟之间,谁先加载谁牛逼(三)实践
Firstly, there is a critical java rule. Suppose there are 2 jars, A.jar and B.jar in the same classloader, which both contain a resource with the same path and name.
If ClassLoader.getResource(resource) is called in A.jar, it won’t look for the resource in A.jar on priority, which means it won’t definitely get the resource in A.jar.
Which resource on earth it will get is determined by which jar is loaded by the classloader earlier.
In addition, the load order is not determined by alphabet on linux, actually it’s a random procedure by linux hard disk node order, of course it is random and cannot be controlled.
I’ve designed a demo to prove the conclusion above successfully.
classloader getresource jar包资源冲突情况,父亲为大,兄弟之间,谁先加载谁牛逼(二)的结论
With regard to what happened to our project, I found 4 batch-hsql.properties in project classpath:
And they all have the same path ( resources/batch-hsql.properties), please ignore the one at project-war\src\main\resoureses at first.
It is noticed spring-batch-core-4.2.4.RELEASE.jar!resources/batch-hsql.properties has no key named ‘batch.business.schema.script’, so there is 25% chance that spring get the property from this file, which contributed to the random startup failure.
Then let’s talk about WebAppClassLoader of tomcat.
This classloader will load the resources such as class files and other resources in war on priority, then it will load the jars in dependency, which means war’s resources are always in the front of all the resources with the same path and name.
So I believe batch-hsql.properties at war will always be read by spring.
Besides, there’s no batch-default.properties in spring-batch-core, which is the reason this never happened before, all the files were qualified for spring.
关于jar加载顺序:
https://www.jianshu.com/p/dcad5330b06f
调用的是java.io.File类list()方法,list调的是UnixFileSystem的native的list()方法。
继续向下查是文件系统的实现,CentOS 6使用的是Ext4,文件顺序与目录文件的大小是否超过一个磁盘块和文件系统计算的Hash值有关。
总结
因Java语言的跨平台特性,在class首次从jar中找到对应的文件时,查找的顺序是文件操作系统实现决定,与inode值无关。那么像active-all.jar将依赖一起打包的方式极易出现这类问题!!!
浙公网安备 33010602011771号