2016-03-11 68 views
0

我正在考慮修改現有的java框架以使用OSGi。我有幾個依賴反射的組件,並且可以與任何類型的類(如bean和持久性服務)一起工作。 我對OSGi還不是很有經驗,但據我瞭解,OSGi包只能看到它明確導入的包中的類。如果我用maven-bundle-plugin構建一個包,並指定通配符作爲導入包,它將解析構建時由代碼引用的包。我需要代碼來處理構建時未知的包中的類。使用maven構建基於反射的OSGi服務

我想要實現的是,bundle-A可以使用bundle-B中的持久性框架來保存屬於bundle-C的類。雖然bundle-B在構建時不知道bundle-C。

我需要什麼樣的清單條目以及如何使用maven-bundle-plugin來設置它們?

此外,由於可以有多個版本的相同的類使用不同的捆綁包,這甚至在OSGi環境中有意義嗎?如果我理解正確,Bundle-A和Bundle-B可能會看到Bundle-C的不同組合。如果Bundle-A現在將位於Bundle-C中的類的對象傳遞給Bundle-B,Bundle-B然後使用該類上的反射,則Bundle-B將按照其在Bundle-C中定義的類或者在Bundle-C中定義的類Bundle-A的Bundle-C。 例如,如果我在捆綁-C以下類:

class Y { 
    [...] 
} 

class X { 
    Y y; 
    [...] 
} 

捆綁-C是用於捆綁-A不同和B B通過類X的一個目的是A.如果B現在發現領域ÿ並解決它的類是否會解析Y,因爲它是Bundle-C的版本還是A已知的版本?

簡而言之,即使我有一個從所有包中導入所有類的包,這甚至可以用來創建一個服務來將對象保存到數據庫中?

回答

1

當你加載類類加載的整個問題纔有意義。反射在OSGi中的工作方式與外部OSGi相同。

所以,如果你有一個方法捆綁b,把一個對象作爲參數。然後你可以從bundle A中調用這個方法,並在bundle c中定義一個Class的實例。即使bundle b沒有爲該對象的包導入,它仍然可以使用反射來處理該對象。

如果您希望在不導入包的包中按名稱加載類,那麼安全的方法是將其包含類的包的類加載器。

因此,例如,你可以在捆B這個方法:

public Object loadTest(ClassLoader loader, String name) { 
    return loader.loadClass(name); 
} 

現在的問題當然是如何讓包B的包一個類加載器的。最簡單的方法是使用MyClass myObject = new MyClass()從b創建一個類。捆綁一個可以做到這一點,因爲它導入包。然後您可以使用myObject.getClass().getClassLoader()來獲取bundle b的類加載器。

在OSGi中,每個對象的類加載器都是它定義的包的類加載器(如果你不做任何奇怪的事情)。

如果這是不可能的,你可以通過使用

ClassLoader loader = bundle.adapt(BundleWiring.class).getClassLoader(); 
+0

謝謝。因此,如果一個類由類加載器加載,則其字段的類也由相同的類加載器填充。我認爲當getFields被調用時,線程的類加載器可能會延遲加載它,這會看到不同版本的字段類。我想這意味着調用newInstance將使用構造類的類加載器而不是調用者的類加載器。如果您不介意另外一個問題,我可以依賴具有不同哈希碼的相同類的不同版本,還是依賴於JVM?我需要緩存每個類的DAO(-version) – user3240383

+0

OSGi類加載不使用線程上下文類加載器。 這些字段通常由它們所在類的bunde類加載器加載..但是如果字段類位於該包之外,則此類加載器引用其他bundle類加載器。所以字段類可能有不同的類加載器。 我認爲hashcodes應該是不同的,但從來沒有嘗試過。 –

+0

類的標識來源於完全限定的類名和定義它的類加載器。 hashCode不會幫助你區分類。 –

0

您在一篇文章多個問題:)

對於在OSGi環境可能你check my blog建立JPA。

OSGi環境中的JPA實現以另一種方式工作。它掛接到一個包監聽器,如果一個包以持久化(@Entity)類啓動,它將加載它們。

關於類版本:

一般 - 如果你想要一些服務捆綁認識到你的類,你可以「注入」它使用束片段。在你的情況 - 你有一個直接的依賴關係(X取決於Y),因此任何加載類X的bundle都將加載Y類(使用特定版本)。

在OSGi環境中,您可以使用不同的類版本,但不可混用它們。實際上,一個包依賴於特定的類版本(聲明或首次發現)。事實上 - 每個類都由其名稱和類加載器標識來標識。因此,迫使bundle使用來自不同類加載器(版本)的相同類將導致「類加載器中毒」和大量難以追蹤的異常。

玩得開心

+0

感謝您的附加信息獲得一個捆綁的類加載器。我應該提到我使用我自己的不是JPA的持久性框架。 – user3240383