玩大發了,Tomcat 8.5 升級有坑…


最近某全系統做了環境升級:

  • Tomcat 8.5.x
  • JDK 1.8.x

有個系統升級后出現沒有這個方法異常:

threw exception; nested exception is java.lang.NoSuchMethodError: 
...
...

上線后系統起不來,這下玩大了。。。

咋一看應該是 jar 包沖突了,經過排查,果然是 jar 包沖突了,類路徑下存在了幾個不同版本類似的 jar 包,是由另外一個依賴引入進來的 compile 依賴,然后排除沖突的依賴就解決了。

那么問題來了,既然 jar 包沖突,相同的環境,為什么在開發環境、測試環境、預上線環境都沒有出現問題?

經過查證,那是因為 Tomcat 8 之后的 jar 包加載方式變了,8 之前是按照字母順序加載的,而 8 之后就變了,Tomcat 使用的是 File.listFiles() 方法來獲取目前下的 jar 包,加載的順序就和文件系統返回的順序有關,就不一定是按字母排序了。

java.io.File#listFiles() 源碼注釋:

這個方法是獲取目前下的所有文件,它不能保證按指定的順序返回結果,特別是,不能保證按字母順序返回。為什么本地環境可以,可能是剛好是按字母排序的了。

那么,這個問題的解決辦法可以是:

1)如果是沖突問題,排除沖突依賴解決 jar 包沖突或者降級到 tomcat 7 就行了,又或者是寫個腳本檢查一下包名是否有重復的包;我們剛好是有兩個 jar 包沖突了,解決沖突就正常了;

2)如果是業務問題,我們都知道 JVM 雙親委派機制,同一個類是不能重復加載的,如果業務確實需要加載多個版本的依賴,那就需要實現自己的自定義類加載器分別去加載對應的 jar 包;

關於類加載器、雙親委派機制都可以在Java技術棧公眾號往期文章找到相對應的解答。

關注公眾號Java技術棧回復"面試"獲取我整理的2020最全面試題及答案。

推薦去我的博客閱讀更多:

1.Java JVM、集合、多線程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架構、阿里巴巴等大廠最新面試題

覺得不錯,別忘了點贊+轉發哦!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM