簡體   English   中英

Java Classloader - 如何引用jar的不同版本

[英]Java Classloader - how to reference different versions of a jar

這是一個常見問題。 我正在使用2個庫A.jarB.jar ,這些庫依賴於同一個jar的不同版本。
假設在運行時我需要THIS.xxxjar

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

我可以針對它的依賴編譯特定的jar(A.jar / B.jar)但是在運行時我只能加載1個版本。 哪一個?
僅加載1個依賴項(最新版本)意味着如果庫不是向后兼容的,那么我的代碼可能會拋出運行時異常(那里有向后兼容的庫嗎?)。

無論如何,我知道像OSGi這樣的東西可以解決這個問題。
我想知道解決這類問題的舊方法是什么......

非常感謝

你提到的“舊方法”(以及OSGI當然使用的一種方法)是為依賴關系的兩個分支安裝自己的ClassLoader。 例如,應用程序服務器就能夠在同一個JVM中運行相同應用程序的較舊版本和較新版本。

閱讀類加載器層次結構。

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

OSGi可以解決這個問題。 OSGi包只不過是一個帶有額外元數據詳細說明版本的jar。 捆綁包具有版本號,並將詳細說明從屬罐的版本號(或范圍)。

有關更多信息,請查看這篇介紹性的Javaworld文章

要在沒有OSGi的情況下解決這個問題,就必須手動確保使用兼容的jar進行編譯和運行。 正如您所發現的,這不一定是一項微不足道的任務。 由於jar不一定能識別它們的版本,因此唯一可靠的方法是記錄/比較校驗和或簽名。

許多庫是向后兼容的。 但不是所有的..


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

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

如果需要,您可以修改一下與舊依賴項一起使用的庫...
這需要訪問源...


請注意,編譯時兼容性也不能保證正確的運行時行為。 這是一步,你可以:

  • 閱讀WhatsNew文件,了解新版本的jar
  • 在互聯網上查找報告兼容性問題的用戶
  • 寫JUnits
  • 比較兩個罐子里的代碼

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

引用基本的“oldway”實現checkout https://github.com/atulsm/ElasticsearchClassLoader

這提供了一種處理elasticsearch客戶端使用的非向后兼容版本的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM