最近工作当中遇到过好几例,由于项目当中依赖了一些框架,而这些框架无法直接修改时,我就直接本地代码写了一个同名同包路径的类,可以直接覆盖框架的类(本文说的框架类,不包括jdk的),屡试不爽。但是心里不免有疑问,为啥我本地写的同名同路径的类,可以覆盖三方框架的类呢?如果我依赖了jarA和jarB,俩jar包有一个同名同路径的类,那JVM会加载哪一个类呢?听同事说过,他们之前遇到过一同名同路径的类问题,测试环境和生产环境加载jar包的顺序不一样,导致出现线上事故。有这些疑问,心里也比较慌,所以特意花了些时间研究了下。

谁控制jar包的加载顺序的?

查了很多资料,比较靠谱的说法是,操作系统本身,控制了jar包的默认加载顺序。

而jar包的加载顺序,是跟classpath这个参数有关,当使用idea启动springboot的服务时,可以看到classpath参数的:

-classpath "/Users/luoxiaohui/Develop/codeyun/java_advanced/eureka-feign-demo/eureka-feign/target/classes:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-starter-netflix-eureka-server/2.1.0.RELEASE/spring-cloud-starter-netflix-eureka-server-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-starter/2.1.0.RELEASE/spring-cloud-starter-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-context/2.1.0.RELEASE/spring-cloud-context-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/security/spring-security-crypto/5.1.6.RELEASE/spring-security-crypto-5.1.6.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-commons/2.1.0.RELEASE/spring-cloud-commons-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/security/spring-security-rsa/1.0.7.RELEASE/spring-security-rsa-1.0.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/bouncycastle/bcpkix-jdk15on/1.60/bcpkix-jdk15on-1.60.jar:/Users/luoxiaohui/.m2/repository/org/bouncycastle/bcprov-jdk15on/1.60/bcprov-jdk15on-1.60.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-netflix-eureka-server/2.1.0.RELEASE/spring-cloud-netflix-eureka-server-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.1.7.RELEASE/spring-boot-starter-web-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.1.7.RELEASE/spring-boot-starter-json-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.9.9/jackson-datatype-jdk8-2.9.9.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.9.9/jackson-datatype-jsr310-2.9.9.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.9.9/jackson-module-parameter-names-2.9.9.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.1.7.RELEASE/spring-boot-starter-tomcat-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.22/tomcat-embed-core-9.0.22.jar:/Users/luoxiaohui/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.22/tomcat-embed-el-9.0.22.jar:/Users/luoxiaohui/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.22/tomcat-embed-websocket-9.0.22.jar:/Users/luoxiaohui/.m2/repository/org/hibernate/validator/hibernate-validator/6.0.17.Final/hibernate-validator-6.0.17.Final.jar:/Users/luoxiaohui/.m2/repository/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar:/Users/luoxiaohui/.m2/repository/org/jboss/logging/jboss-logging/3.3.2.Final/jboss-logging-3.3.2.Final.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/classmate/1.4.0/classmate-1.4.0.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-web/5.1.9.RELEASE/spring-web-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-beans/5.1.9.RELEASE/spring-beans-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-webmvc/5.1.9.RELEASE/spring-webmvc-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-aop/5.1.9.RELEASE/spring-aop-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-expression/5.1.9.RELEASE/spring-expression-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-actuator/2.1.7.RELEASE/spring-boot-starter-actuator-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-actuator-autoconfigure/2.1.7.RELEASE/spring-boot-actuator-autoconfigure-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-actuator/2.1.7.RELEASE/spring-boot-actuator-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/io/micrometer/micrometer-core/1.1.5/micrometer-core-1.1.5.jar:/Users/luoxiaohui/.m2/repository/org/hdrhistogram/HdrHistogram/2.1.9/HdrHistogram-2.1.9.jar:/Users/luoxiaohui/.m2/repository/org/latencyutils/LatencyUtils/2.0.3/LatencyUtils-2.0.3.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-freemarker/2.1.7.RELEASE/spring-boot-starter-freemarker-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/freemarker/freemarker/2.3.28/freemarker-2.3.28.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-context-support/5.1.9.RELEASE/spring-context-support-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-netflix-hystrix/2.1.0.RELEASE/spring-cloud-netflix-hystrix-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-aop/2.1.7.RELEASE/spring-boot-starter-aop-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/aspectj/aspectjweaver/1.9.4/aspectjweaver-1.9.4.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-netflix-eureka-client/2.1.0.RELEASE/spring-cloud-netflix-eureka-client-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/com/netflix/eureka/eureka-client/1.9.8/eureka-client-1.9.8.jar:/Users/luoxiaohui/.m2/repository/org/codehaus/jettison/jettison/1.3.7/jettison-1.3.7.jar:/Users/luoxiaohui/.m2/repository/stax/stax-api/1.0.1/stax-api-1.0.1.jar:/Users/luoxiaohui/.m2/repository/com/netflix/netflix-commons/netflix-eventbus/0.3.0/netflix-eventbus-0.3.0.jar:/Users/luoxiaohui/.m2/repository/com/netflix/netflix-commons/netflix-infix/0.3.0/netflix-infix-0.3.0.jar:/Users/luoxiaohui/.m2/repository/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar:/Users/luoxiaohui/.m2/repository/joda-time/joda-time/2.10.3/joda-time-2.10.3.jar:/Users/luoxiaohui/.m2/repository/org/antlr/antlr-runtime/3.4/antlr-runtime-3.4.jar:/Users/luoxiaohui/.m2/repository/org/antlr/stringtemplate/3.2.1/stringtemplate-3.2.1.jar:/Users/luoxiaohui/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar:/Users/luoxiaohui/.m2/repository/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar:/Users/luoxiaohui/.m2/repository/org/apache/commons/commons-math/2.2/commons-math-2.2.jar:/Users/luoxiaohui/.m2/repository/javax/ws/rs/jsr311-api/1.1.1/jsr311-api-1.1.1.jar:/Users/luoxiaohui/.m2/repository/com/netflix/servo/servo-core/0.12.21/servo-core-0.12.21.jar:/Users/luoxiaohui/.m2/repository/com/sun/jersey/jersey-core/1.19.1/jersey-core-1.19.1.jar:/Users/luoxiaohui/.m2/repository/com/sun/jersey/jersey-client/1.19.1/jersey-client-1.19.1.jar:/Users/luoxiaohui/.m2/repository/com/sun/jersey/contribs/jersey-apache-client4/1.19.1/jersey-apache-client4-1.19.1.jar:/Users/luoxiaohui/.m2/repository/org/apache/httpcomponents/httpclient/4.5.9/httpclient-4.5.9.jar:/Users/luoxiaohui/.m2/repository/org/apache/httpcomponents/httpcore/4.4.11/httpcore-4.4.11.jar:/Users/luoxiaohui/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar:/Users/luoxiaohui/.m2/repository/com/google/inject/guice/4.1.0/guice-4.1.0.jar:/Users/luoxiaohui/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar:/Users/luoxiaohui/.m2/repository/com/github/vlsi/compactmap/compactmap/1.2.1/compactmap-1.2.1.jar:/Users/luoxiaohui/.m2/repository/com/github/andrewoma/dexx/dexx-collections/0.2/dexx-collections-0.2.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.9.9/jackson-core-2.9.9.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.9/jackson-databind-2.9.9.jar:/Users/luoxiaohui/.m2/repository/com/sun/jersey/jersey-servlet/1.19.1/jersey-servlet-1.19.1.jar:/Users/luoxiaohui/.m2/repository/com/sun/jersey/jersey-server/1.19.1/jersey-server-1.19.1.jar:/Users/luoxiaohui/.m2/repository/com/netflix/eureka/eureka-core/1.9.8/eureka-core-1.9.8.jar:/Users/luoxiaohui/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.4.1/woodstox-core-asl-4.4.1.jar:/Users/luoxiaohui/.m2/repository/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar:/Users/luoxiaohui/.m2/repository/com/netflix/archaius/archaius-core/0.7.6/archaius-core-0.7.6.jar:/Users/luoxiaohui/.m2/repository/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar:/Users/luoxiaohui/.m2/repository/com/google/guava/guava/16.0/guava-16.0.jar:/Users/luoxiaohui/.m2/repository/javax/inject/javax.inject/1/javax.inject-1.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.9.9/jackson-dataformat-xml-2.9.9.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/jackson/module/jackson-module-jaxb-annotations/2.9.9/jackson-module-jaxb-annotations-2.9.9.jar:/Users/luoxiaohui/.m2/repository/org/codehaus/woodstox/stax2-api/3.1.4/stax2-api-3.1.4.jar:/Users/luoxiaohui/.m2/repository/com/fasterxml/woodstox/woodstox-core/5.0.3/woodstox-core-5.0.3.jar:/Users/luoxiaohui/.m2/repository/com/thoughtworks/xstream/xstream/1.4.10/xstream-1.4.10.jar:/Users/luoxiaohui/.m2/repository/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar:/Users/luoxiaohui/.m2/repository/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-starter-netflix-archaius/2.1.0.RELEASE/spring-cloud-starter-netflix-archaius-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-netflix-ribbon/2.1.0.RELEASE/spring-cloud-netflix-ribbon-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-netflix-archaius/2.1.0.RELEASE/spring-cloud-netflix-archaius-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/commons-configuration/commons-configuration/1.8/commons-configuration-1.8.jar:/Users/luoxiaohui/.m2/repository/commons-lang/commons-lang/2.6/commons-lang-2.6.jar:/Users/luoxiaohui/.m2/repository/org/springframework/cloud/spring-cloud-starter-netflix-ribbon/2.1.0.RELEASE/spring-cloud-starter-netflix-ribbon-2.1.0.RELEASE.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon/2.3.0/ribbon-2.3.0.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon-transport/2.3.0/ribbon-transport-2.3.0.jar:/Users/luoxiaohui/.m2/repository/io/reactivex/rxnetty-contexts/0.4.9/rxnetty-contexts-0.4.9.jar:/Users/luoxiaohui/.m2/repository/io/reactivex/rxnetty-servo/0.4.9/rxnetty-servo-0.4.9.jar:/Users/luoxiaohui/.m2/repository/com/netflix/hystrix/hystrix-core/1.5.18/hystrix-core-1.5.18.jar:/Users/luoxiaohui/.m2/repository/io/reactivex/rxnetty/0.4.9/rxnetty-0.4.9.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon-core/2.3.0/ribbon-core-2.3.0.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon-httpclient/2.3.0/ribbon-httpclient-2.3.0.jar:/Users/luoxiaohui/.m2/repository/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar:/Users/luoxiaohui/.m2/repository/com/netflix/netflix-commons/netflix-commons-util/0.3.0/netflix-commons-util-0.3.0.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon-loadbalancer/2.3.0/ribbon-loadbalancer-2.3.0.jar:/Users/luoxiaohui/.m2/repository/com/netflix/netflix-commons/netflix-statistics/0.1.1/netflix-statistics-0.1.1.jar:/Users/luoxiaohui/.m2/repository/io/reactivex/rxjava/1.3.8/rxjava-1.3.8.jar:/Users/luoxiaohui/.m2/repository/com/netflix/ribbon/ribbon-eureka/2.3.0/ribbon-eureka-2.3.0.jar:/Users/luoxiaohui/.m2/repository/org/slf4j/slf4j-api/1.7.26/slf4j-api-1.7.26.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.7.RELEASE/spring-boot-starter-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot/2.1.7.RELEASE/spring-boot-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-context/5.1.9.RELEASE/spring-context-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.7.RELEASE/spring-boot-autoconfigure-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.7.RELEASE/spring-boot-starter-logging-2.1.7.RELEASE.jar:/Users/luoxiaohui/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/luoxiaohui/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/luoxiaohui/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.2/log4j-to-slf4j-2.11.2.jar:/Users/luoxiaohui/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.2/log4j-api-2.11.2.jar:/Users/luoxiaohui/.m2/repository/org/slf4j/jul-to-slf4j/1.7.26/jul-to-slf4j-1.7.26.jar:/Users/luoxiaohui/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/Users/luoxiaohui/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-core/5.1.9.RELEASE/spring-core-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/org/springframework/spring-jcl/5.1.9.RELEASE/spring-jcl-5.1.9.RELEASE.jar:/Users/luoxiaohui/.m2/repository/javax/xml/bind/jaxb-api/2.3.1/jaxb-api-2.3.1.jar:/Users/luoxiaohui/.m2/repository/javax/activation/javax.activation-api/1.2.0/javax.activation-api-1.2.0.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar"

包路径越靠前,越先被加载。换句话说,如果靠前的jar包里的类被加载了,后面jar包里有同名同路径的类,就会被忽略掉,不会被加载。

而且,使用idea启动服务时,可以通过idea直接修改classpath
在这里插入图片描述
如果我们将<module source>(也就是我们自己写的类)拖到最下面,可以发现,我们本地写的跟三方框架同名同路径的类,并不会被加载,也不会覆盖三方框架的类。

我们如何控制jar包的加载顺序?

由于jar包的默认加载顺序,是操作系统本身控制的,但是我们可以通过修改classpath,从而来调整jar包加载顺序。

参考资料

https://www.cnblogs.com/saaav/p/7716179.html
https://docs.oracle.com/javase/8/docs/technotes/tools/findingclasses.html#jarclass
https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐