天天看點

Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤

網上找了很多,都沒有找到想要的,記錄一下自己這次誤打誤撞解決依賴包沖突問題。

環境:工具Myeclipse2014 ,S2SH對應版本如下:

<struts2Version>2.3.30</struts2Version>
<springVersion>4.2.3.RELEASE</springVersion>
<hibernateVersion>4.3.11.Final</hibernateVersion>
           

以 java.lang.NoSuchMethodError: org.springframework.core.io.ResourceEditor.錯誤為例(據說這玩意一般是依賴包沖突造成的,或者由于jar包版本問題,調用的方法已經改變,某個版本jar所調用的方法傳入的參數與你目前使用的版本所定義的方法傳入的參數不一樣。)

Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤

如果有JAD反編譯插件(安裝一個也很簡單,上網搜尋一下就有教程,挺有用的插件),點選藍色連結部分–init(GenericFilterBean.java:167)會自動跳轉到反編譯生成的Java檔案(非原始源代碼)。Ctrl+F查找轉到init方法處,檢視方法體邏輯,可能會存在多個輸入參數不同的init方法,找到方法中有調用ResourceEditor相關的那個init方法。

Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤

init方法調用ResourceEditor的構造器參數是ResourceLoader類型的,在左側的Package Explorer依次展開Maven項目名—>Maven Dependencies,找到ResourceEditor類所在的jar包,打開該類如下,此版本的jar包沒有對應的ResourceEditor構造器,就是這個原因報錯。

Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤

有的時候修改pom.xml檔案相應jar包的版本就可以解決,有的時候,你打開pom.xml檔案想修改版本卻發現你根本沒有引用該jar包(sun the dog)。如果是用Maven管理jar包,即使你沒有在pom.xml檔案裡申明使用該jar包,由于jar包之間的依賴,Maven也會自動導入某個jar包依賴的其它jar包(友善管理jar包的同時也帶來了難以分析哪些個jar包沖突)。

解決方案(靠運氣,可能也要看臉=.=):

  • 導緻錯誤的包好找(Maven可以檢視某個jar包調用了哪些jar包,要看哪些個jar包調用了這個jar包在Myeclipse下點選該jar包,右鍵maven->Exclude Maven Artifacets->preview檢視從哪些個地方進行了exclusion),org.springframework.core屬于spring-core這個包,但是是哪個包調用它導緻錯誤呢,在錯誤資訊顯示的調用棧,往下一級一級确定是哪個包出了問題(這個有點靠運氣。。。水準有限,對S2SH的學習還很淺,上網搜一搜一些資訊,猜測是哪個包的問題。。。。),可以先确定是SSH中哪一層的問題,可以縮小懷疑範圍
  • 找到可能是這個包出問題–struts2-spring-plugin。這個包調用的另外某個jar包版本與你項目中所使用的jar包版本不一樣
  • 再次靠臉靠人品,在分析了一個個jar包過程中,一個不小心打開了一個神奇的大門。

    右鍵Maven Dependencies目錄中的jar包,Maven->Open Pom,視窗下有很多檢視方式,切換檢視方式為Dependency Graph,下圖就是神器包了–spring-test.jar依賴樹):

    打開後的依賴jar包樹圖如下(這是項目無錯誤運作後的依賴樹圖,運作錯誤的依賴樹圖調用的spring-web版本是3.0.5.RELEASE):點選檢視大圖

    Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤
  • 找到spring-core可以看到它被哪些包調用以及調用了哪些包,在錯誤資訊顯示的調用棧看出是org.springframework.web.filter調用spring-core導緻了錯誤,再看是哪個包調用了org.springframework.web這個jar包,一級級往上,将有問題的版本号從調用它的上級jar包中排除,然後另外導入合适版本的jar包,最好上下級使用統一的版本号
    Maven的Jar包沖突導緻java.lang.NoSuchMethodError錯誤
  • 在pom.xml檔案中排除調用的沖突版本,并添加新版本jar包如下:
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>4.2.3</version>
    <!-- 排除此處引用的spring-web-3.0.5的包,另外使用4.2.3包,解決包沖突成功 -->
    <exclusions>
        <exclusion>
            <artifactId>spring-web</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.3</version>
</dependency>
           

繼續閱讀