2015-06-13 32 views
1

如何防止AntClassLoader和URLClassLoader導致鏈接錯誤?ant LinkageError without includeantruntime

由於較舊的項目,junit和hamcrest.core被放入ANT_HOME,我們的構建使用includeantruntime = true來運行單元測試。

我現在正在使用ant構建的項目,我不想依賴ANT_HOME中的任何jar文件。我在所有的javac節中都使用includeantruntime = false。

但是,現在我正在使用hamcrest進行測試,我得到一個運行時鏈接錯誤。

java.lang.LinkageError: loader constraint violation: when resolving method 
"org.junit.Assert.assertThat(Ljava/lang/Object;Lorg/hamcrest/Matcher;)V" 
the class loader (instance of org/apache/tools/ant/loader/AntClassLoader5) 
of the current class, myclass, and the class loader (instance of 
java/net/URLClassLoader) for resolved class, org/junit/Assert, have different 
Class objects for the type assertThat used in the signature 

當junit運行測試時發生運行時鏈接錯誤。

我似乎有兩個選擇,而且我喜歡:從ANT_HOME

  1. 刪除JUnit和hamcrest.core。這打破了其他 項目。
  2. 從項目中刪除junit和hamcrest.core,並依賴於ANT_HOME中的設置 。這是我想要避免的。

我本來以爲包括行爲會有幫助。

我的目標是允許junit和hamcrest.core留在ANT_HOME中,同時也包括他們在項目中。也就是說,ANT_HOME的內容應該不重要。

有沒有解決這個問題的方法?

回答

1

有兩個步驟來解決這一問題:

  1. 添加<pathelement path="${java.class.path}" />爲測試環境中的類路徑。
  2. fork="true"添加到junit元素的屬性中。您也可以爲junit元素選擇分叉模式。例如,我使用forkmode="once"

includeantruntime對於所有條件都應該保留false

允許junit fork將ant類加載器從ant類加載器中顯式分離,從而防止任何無意的關聯。需要java.class.path來明確允許ant找到所有需要執行的類。

使用這些設置,不會使用ant lib目錄中的庫,並且不會影響JUnit測試。

0

設置「includeantruntime = false」是一件好事。它迫使你的構建更獨立,更少依賴於本地機器的配置,我喜歡稱之爲「魔法構建服務器」(沒人真的知道它是如何工作的)的問題。

我使用Apache ivy來管理我的ANT類路徑依賴關係。下面給出了在當地的「lib」目錄使用廣口瓶的例子:

常春藤的真正威力在於當你與Maven倉庫結合起來。您的源代碼仍然可移植,但不必隨其所有第三方罐一起提供。起初它似乎令人望而生畏,但它是一種值得研究的方法。有一些事情,馬文得到正確的:-)

希望這會有所幫助。