2011-10-12 70 views
1

我對OSGi非常陌生。OSGi類加載器問題

我開發一個插件A(OSGi包),假設取決於庫,假設B-1.0C-1.0。現在如果庫C-1.0取決於庫B-2.0(注意:不同版本的庫B)。所以我的插件在其類路徑中有兩個不同版本的庫B。現在,我該如何處理這種情況?

正如我在過去4-5天研究OSGi,它爲JIRA應用程序中的每個插件創建一個類加載器,因此插件之間不會出現依賴關係版本不匹配。但是開發人員會做什麼如果插件本身需要兩個不同版本的庫jar?

我可以通過OSGi在單個osgi包中創建兩個不同的類加載器,比如一個用於包X,另一個用於包Y?

請幫助我在上述任何情況下或指向正確的方向。

在此先感謝。

+0

感謝所有您的解決方案,並非常抱歉我的遲交回復,但您提供的解決方案假定這些全部都是OSGi捆綁包。好的,讓我重述一下我的問題,我的問題是我只有一個OSGi捆綁軟件**插件A **,其他都是簡單的庫,而不是OSGi捆綁軟件包。一個單獨的OSGi包如何使用庫** B-1.0 **作爲它的一個包說** com.example.foo **並且使用庫** B-2.0 **作爲另一個包說** com.example。酒吧**。 (這就是爲什麼我要求在一個OSGi包中創建兩個不同的類加載器。) –

回答

0

在osgi包或插件中,如果您傳遞的是額外的版本= 2.0,那麼它將定義導入哪些類,如果您未指定,則它將使用B-2.0中的類任何東西,然後它會解析到一個由classloader首先加載的。

即 進口包裝(C 1.0): b.some.package; version =「2.0」或b.some.package;版本=「[2.0,4.0)」

import-package(A 1.0): b.some.package;版本=「1.0」或b.some.package;版本= 「1.0」

希望這有助於

阿努普

0

由於每個OSGi包有它自己的類加載器,將有4束在運行時,也4類加載器(A,B-1.0, B-2.0,C-1.0)。

您可能在B中包含了兩個相同類的副本(一個來自1.0,另一個來自2.0)。如果你運行這個,你可能會在A代碼中碰到一個ClassCastException,因爲B類的兩個版本是不一樣的。

OSGi提供了一個「用法」子句來儘早檢測這種情況。例如,C可以有使用類似的條款如下:

Export-Package: c.some.package;uses="b.some.package";version="1.0" 
Import-Package: b.some.package;version="2.0" 

在這種情況下,你將有一個早期故障(同時解決A),被稱爲使用衝突,因爲C放置一個約束的其對B的可接受版本

概念消費,解決這個問題的唯一方法是讓B的消費者(A和C在這種情況下)同意B的版本

1

記住捆綁不依賴於其他捆綁

進口包出口由其他包。 (除非你使用Require-Bundle,但你不應該)。所以,從你的例子改寫的場景:

  • 捆綁一個進口包裝org.foo。捆綁C出口包org.foo,和OSGi導入導出到出口。到現在爲止還挺好。

  • Bundle C也進口包org.bar。包B 1.0出口包org.bar。因此OSGi將這些連接在一起,一切都很好。

  • 現在...捆綁A也進口包org.wibble。套裝B 2.0出口包裝org.wibble。這也很好! Bundles B 1.0 and B 2.0就OSGi而言只是簡單的不同包,它們都可以同時安裝。

所以,當你在依賴他們實際的工作方式,你會發現這是完全可能的一個導入來自兩個不同的版本的代碼。但是有一個限制。考慮以下幾點:

  • 捆綁d進口包org.fooorg.bar v1.0(是的,包版本)。
  • 捆綁E出口包org.foo,滿足進口D。包E也進口包org.bar v2.0
  • 某些其他軟件包(說F v1F v2)導出org.bar包的2個版本。

實際上這種情況仍然可以工作。 d可以從某處導入包org.bar的1.0版,和Ë可以從其他地方如dË導入包org.foo導入包org.bar的2.0版,在同一時間。我個人覺得這很不可思議!但是,如果org.foo「使用」org.bar,則它不起作用,其中「使用」表示org.bar中的某些類型在org.foo的API中可見。在這種情況下,軟件包D將暴露於2個不同的副本org.bar,這是不允許的,因此OSGi將通過不允許進入RESOLVED或ACTIVE狀態來阻止軟件包D運行。