JAR衝突問題的解決
導讀 | 今天碰到群裡小夥伴問,線上程式好像有多個不同版本的Netty包,怎麼去看到底載入了哪一個? |
在說如何看之前,先來說說,當你開始意識到專案裡有多個不同版本的Jar包,都是因為遇到了這幾個異常:
- 1、java.lang.NoSuchMethodException:自己程式碼中呼叫了某個方法,因為載入了其他版本的jar,這個版本正好沒這個方法。
- 2、java.lang.NoClassDefFoundError:編譯時候是好的,但是執行的時候,因為載入的jar版本問題,沒有這個類。
- 3、java.lang.ClassNotFoundException:在動態載入某個Class的時候,因為要載入的jar不是正確的版本,而導致找不到這個類。
當你在本地執行ok,但到伺服器上發現出現這些錯誤的時候,就要意識到很可能是jar衝突了(有相同依賴存在多個版本)。這個問題往往也會有這樣的表現:多例項部署的時候,有的例項是好的,有的例項則不行。
根據之前分析的異常種類,我們可以去執行中的現場確認當前載入的問題。
這裡我們可以使用阿里開源的Arthas工具,如果第一次用,那麼按下面操作先安裝再執行:
curl -O java -jar arthas-boot.jar
執行好之後,會列印出當前執行著的java應用,比如:
[INFO] arthas-boot version: 3.4.6 [INFO] Process 40611 already using port 3658 [INFO] Process 40611 already using port 8563 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 40611 chapter4-3-0.0.1-SNAPSHOT.jar [2]: 37786
透過輸入編號選擇要檢視的java應用,比如這裡選擇:1,進入到chapter4-3-0.0.1-SNAPSHOT.jar中去。
下面介紹兩個重要 :
第一個:sc ,我們確認一下可能衝突的jar包下面,是否有對應的class。有些不同版本包下class就不一樣,馬上就可以分辨出來。
比如,透過下面的命令,我們檢視一下com.didispace包下有什麼類:
[arthas@40611]$ sc com.didispace.* com.didispace.chapter43.Chapter43Application com.didispace.chapter43.Chapter43Application$$EnhancerBySpringCGLIB$$8b82b194 com.didispace.chapter43.UploadController Affect(row-cnt:3) cost in 6 ms.
第二個:sm命令,檢視具體某個類有哪些方法。有的版本差異就是去掉了某個方法,這個時候我們就可以透過這個命令來檢視。
比如,透過下面的命令,我們檢視一下com.didispace.chapter43.UploadController類下有些什麼方法:
[arthas@40611]$ sm com.didispace.chapter43.UploadController com.didispace.chapter43.UploadController ()V com.didispace.chapter43.UploadController create(Lorg/springframework/web/multipart/MultipartFile;)Ljava/lang/String; com.didispace.chapter43.UploadController uploadPage()Ljava/lang/String; Affect(row-cnt:3) cost in 5 ms.
在確認完是載入錯誤的情況下,我們要去解決衝突。那麼解決衝突要做的就是找到到底哪裡衝突了以及我們要去除或者強制
找出版本衝突的方法:使用Maven命令:mvn -U dependency:tree -Dverbose。
命令執行之後,會在控制檯以樹狀形式列出所有依賴內容,然後透過搜尋的方式查詢衝突的包,看看都是從哪個依賴中帶進來的(在IDEA中搜尋會高亮,更容易找到)。
[INFO] com.didispace:chapter4-3:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.4.1:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.4.1:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:2.4.1:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.4.1:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.4.1:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile [INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.13.3:compile [INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.13.3:compile [INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.30:compile [INFO] | | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.27:compile [INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.4.1:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.11.3:compile [INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.11.3:compile [INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.11.3:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.11.3:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.11.3:compile [INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.11.3:compile [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.4.1:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.41:compile [INFO] | | +- org.glassfish:jakarta.el:jar:3.0.3:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.41:compile [INFO] | +- org.springframework:spring-web:jar:5.3.2:compile [INFO] | | \- org.springframework:spring-beans:jar:5.3.2:compile [INFO] | \- org.springframework:spring-webmvc:jar:5.3.2:compile [INFO] | +- org.springframework:spring-aop:jar:5.3.2:compile [INFO] | +- org.springframework:spring-context:jar:5.3.2:compile [INFO] | \- org.springframework:spring-expression:jar:5.3.2:compile [INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.4.1:compile [INFO] | +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile [INFO] | | +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile [INFO] | | | +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile
解決版本衝突的方式主要兩種:
- 1、透過上面的命令找到不需要的版本之後,在引入的依賴中,使用exclusions將其排除
- 2、在pom.xml中強制指定要使用的版本,這樣這個優先順序最高,就不會引入其他版本要帶進來的版本了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2756702/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- git 解決版本衝突問題Git
- weblogic+axis jar包衝突問題的另一個解決方法WebJAR
- Jar包衝突解決方案調研JAR
- maven解決jar包依賴衝突MavenJAR
- jQuey與json.jar的衝突問題JSONJAR
- GO 問題之多版本衝突解決Go
- Maven中解決依賴衝突的問題Maven
- Maven Idea檢視解決jar包衝突MavenIdeaJAR
- 如解決jquery與原生js衝突的問題jQueryJS
- JAR衝突問題的解決以及執行狀態下如何檢視載入的類JAR
- Git Worktree:解決分支依賴衝突的問題Git
- less中解決CSS3的calc衝突問題CSSS3
- 解決echsop相容jquery(transport.js的衝突)的問題jQueryJS
- Android 解決BottomSheetDialog 拖曳衝突問題Android
- maven jar包衝突常見報錯及解決方法MavenJAR
- 解決gerrit commit後pull發生衝突的問題MIT
- 關於 OkHttp 依賴衝突問題的解決過程HTTP
- 解決app中多語音出現的衝突問題APP
- 利用觸發器解決更新主鍵衝突的問題觸發器
- Git 解決衝突Git
- git 解決衝突Git
- HTML中兩個tabs導航衝突問題的解決方法HTML
- 徹底解決SLF4J的日誌衝突的問題
- 如何解決jQuery的美元$符號衝突問題jQuery符號
- jquery如何解決版本之間衝突的問題jQuery
- 解決ScrollView巢狀ViewPager出現的滑動衝突問題巢狀Viewpager
- 程式衝突及其解決
- git pull 衝突解決Git
- windows解決埠衝突Windows
- IP衝突解決方案
- SVN 版本衝突解決
- hash衝突解決方法
- Git衝突解決技巧Git
- 一次特殊的jar包衝突JAR
- git pull衝突的解決方案Git
- 關於hash衝突的解決
- CentOS7安裝MySQL衝突和問題解決小結CentOSMySql
- 用好這幾個技巧,解決Maven Jar包衝突易如反掌MavenJAR