2014-01-23 42 views
2

我有一個Maven的多模塊項目,使用(其中包括)glassfish-jerseyjersey-moxywicket-ioclucenelamdbaj這些都帶有asm,但都具有不同的版本。
最近,我運行測試時遇到了很多麻煩。典型的錯誤,我得到的是:管理行家不同的cglib/ASM版本

java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V 

我讀到這可以通過不同的asm版本引起的。有沒有辦法在它們的依賴中「沙盒」這些不同的asm版本,所以它們不會混淆?

編輯:

我目前的解決方案是使用jarjar,像這樣:

<build> 
    <plugins> 
     <plugin> 
     <groupId>org.sonatype.plugins</groupId> 
     <artifactId>jarjar-maven-plugin</artifactId> 
     <executions> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>jarjar</goal> 
      </goals> 
      <configuration> 
       <includes> 
       <include>cglib:cglib-nodep</include> 
       </includes> 
       <rules> 
       <rule> 
        <pattern>net.sf.cglib.asm.**</pattern> 
        <result>[email protected]</result> 
       </rule> 
       <rule> 
        <pattern>net.sf.cglib.**</pattern> 
        <result>[email protected]</result> 
       </rule> 
       </rules> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 
+1

這正是ASM開發人員自己告訴你應該將asm重新打包到自己的名稱空間而不是直接依賴它的原因([FAQ#15](http://asm.ow2.org/doc/faq.html #Q15)),因爲它不保證在不同版本之間兼容。我很想將這個報告爲澤西島,Lucene等中的一個bug。 –

+1

人們通常使用cglib而不理解它在封面下使用ASM。遺憾的是,Cglib沒有提出這樣的警告。 –

回答

2

儘量明確地加入一些CGLIB V3 *它採用a recent version of ASM類路徑上。遇到的問題是,cglib通過繼承而不是通過委派來修改ASM類書寫器的行爲。但是,ASM通過使其ClassWriter的方法finalfrom any version 4.*執行後者的最佳實踐,但仍有可能覆蓋其方法in version 3。遇到的錯誤是將cglib 2. *與ASM 4. *結合在一起的結果。

幸運的是(對你而言),cglib在其最新版本中相當靜態,即只有很小的API更改,而較新的版本主要由ASM更新組成。如果你幸運的話,這個明確使用cglib v3。*可以解決你的問題。只要沒有任何項目依賴關係對ASM有直接依賴關係,那麼對於像Jersey或Lucene那樣命名的依賴關係來說這似乎是合理的。

如果這不起作用,則需要重新編譯你的一些相關性,而爲了重新包裝直接ASM依賴成不同的名字空間,以解決這些衝突的版本使用的工具,像jarjar。另一種選擇可能是通過一些有條件的兒童優先法術來隔離不同的ASM版本,但這並不如此推薦,因爲這些效果是不可預測的,並且還會導致性能損失。

+0

在cglib 3.1中刪除並從其他項目中排除cglib依賴關係似乎可以做到。謝謝! – RobAu

+0

唉,這個問題在Jenkins和我的Linux環境下解決了;但Windows用戶似乎仍然從中受益。 – RobAu

+0

這應該不會影響類路徑上的結果。我想你的Windows用戶可能會使用另一個IDE來運行應用程序。我想有些東西是由IDE添加到類路徑中的。檢查其中一臺Windows機器上的任何cglib 2.2依賴關係的類路徑。我想有一些類路徑緩存參與。使用IntelliJ時,重新導入所有Maven項目。使用Eclipse時,請使用IntelliJ。 –