2009-10-12 26 views
19

這是一個常見問題。我正在使用2個庫A.jarB.jar並且這些依賴於同一個jar的不同版本。
比方說,在運行時我需要THIS.xxxjarJava Classloader - 如何引用不同版本的罐子

MY.jar 
    -> A.jar -> THIS.1.0.0.jar 
    -> B.jar -> C.jar -> THIS.5.0.0.jar 

我可以編譯特定的罐子(a.jar文件/ B.jar)針對其的依賴,但在運行時我已經加載僅1版。哪一個?
只加載1個依賴項(最新版本)意味着如果庫不向後兼容,我的代碼可能會拋出運行時異常(是否存在向後兼容的庫?)。

無論如何,我知道像OSGi這樣的東西可以解決這個問題。
我不知道什麼是解決這類問題的老路上...

非常感謝

+0

是否有可能實現這個目標?OSGi如何提供幫助?我們再次在OSGi上引入了一種依賴性,這是典型產品軟件開發中的開銷(特別是對於嵌入式系統) – sskumar86 2016-08-17 10:04:45

回答

7

您提到的「舊方式」(以及OSGI當然在引擎蓋下使用)是爲您的依賴關係的兩個分支安裝自己的ClassLoader。例如,應用程序服務器可以在同一個JVM中運行同一應用程序的較舊版本和較新版本。

閱讀關於classloader hierarchy。

在您的設置中,棘手的部分是聯合點,兩個分支的類都會相遇。兩個分支都不能使用加載到另一個分類中的類。使其工作的方法是確保只有通過引導類加載器(JRE類)加載的類或MY.jar的類加載器纔會傳遞到兩個分支。

1

許多圖書館是向後兼容的。但不是全部..


舊的方法是嘗試僅依賴於一個版本。

使用相同版本(最新)編譯兩者可能更安全。
至少你會得到編譯時錯誤,而不是運行時錯誤。

如果需要的話,可以修改一點點你的庫與舊的依賴工程...
這需要訪問源...


請注意,編譯時的兼容性也不能保證正確的運行時行爲。這是一步到位,那麼您可以:

  • 閱讀WhatsNew文件的jar的新版本
  • 看看在互聯網上的用戶報告的兼容性問題
  • 寫JUnits
  • 在比較碼兩個罐子
4

OSGi可以解決這個問題。一個OSGi包只不過是一個具有附加元數據詳細版本的jar。一個bundle有一個版本號,並且會詳細說明依賴jar的版本號(或範圍)。

查看this introductory Javaworld article瞭解更多信息。

要解決這個問題沒有OSGi意味着必須手動確保您編譯並運行兼容的jar。正如你發現那不一定是一件小事。由於jar不一定能夠識別他們的版本,因此唯一可行的方法是記錄/比較校驗和或簽名。

1

正如KLE所提到的,默認方法是依賴於較新的版本。沒有保證,但大多數情況下這是有效的。可能最好的方式(雖然是一個臃腫的方式)正在使用OSGI來克服它。