2011-09-19 28 views
9

根據OSGi文檔,OSGi旨在幫助防止ClassPath問題。OSGi:如何確保類路徑的一致性?

例如,從「OSGi的在行動」:啓動應用程序時,因爲 類路徑是不正確的

ClassNotFoundExceptions。在允許代碼執行之前,OSGi可以通過確保代碼 滿足相關性來提供幫助。

然而,由於我們已將Java應用程序的OSGi,我看到更多的ClassNotFoundExceptions,尤其是NoClassDefFoundErrors比以往任何時候。之前加載正常的類不會被OSGI類加載器找到,更糟糕的是:在運行時會出現錯誤,這意味着除非通過手動測試應用程序的每個角落,否則無法輕鬆檢查它。

例如,我們的應用程序在OSGi下運行得很開心,但我們收到了Beta測試人員的報告,他們無法將文檔導出爲PDF。事實上,當我看着它,我發現這個功能引起記錄異常:

java.lang.NoClassDefFoundError: org/w3c/dom/Node 

所以,是的OSGi實際上創造了更多的類路徑的問題比它解決的?

更重要的是:我如何測試我的類路徑是否一致,以及所有必要的導入包聲明等。之前我在錯誤報告中瞭解它們?

+0

「除了通過手動測試應用程序的每一個角落」 - 嗯自動化測試? (這同樣適用於任何應用程序)如果您在遷移之前已經有測試套件,那麼您在測試人員發現之前就已經發現了這些錯誤。爲了測試你的bundle是否正確連接,你需要做一些集成測試 - 我們使用Pax Exam來進行測試,並且有很短的集成測試(當前包和它的合作者)以及一些較長的端到端測試(測試整個應用程序)。 – earcam

回答

12

一個OSGi應用程序如果你的清單是正確的將不會拋出ClassNotFoundExceptions和NoClassDefFoundErrors 。也就是說,你需要告訴OSGi你的包使用了哪些包;如果你沒有正確或誠實地做到這一點,那麼OSGi不能幫助你。換句話說:GIGO(垃圾進入,垃​​圾進出)。

例如,您使用包org.w3c.dom,但是您沒有在Import-Package語句中列出它。因此OSGi不知道你需要訪問那個包,所以當你真正嘗試從這個包中加載類時,它們是不可用的。

因此,您需要確保Import-Package聲明對於您的捆綁軟件實際使用的軟件包是準確的。好消息是,「bnd」工具可以通過生成捆綁清單,使用字節碼分析來查找所有靜態引用的包,從而爲您做到這一點。

更新: 您的最終問題是詢問如何在運行時發現問題之前測試捆綁包是否一致。 Bnd有一個「驗證」功能,可以做到這一點。實際上,如果您首先使用Bnd生成清單,那麼您將不需要驗證功能。但是,我不知道有關構建過程的任何信息,所以您可能會發現很難在短期內轉移到基於Bnd的構建中......在這種情況下,將驗證任務添加爲後處理將相對簡單,在構建之後的處理步驟。不過,我仍然建議在構建過程中儘早使用Bnd。

+0

我不知道bnd驗證功能,非常好知道! – amarillion

+3

「如果您的清單是正確的」....意味着您的清單是否與您所使用的特定實現完全相同,並且您沒有做任何事情,OSGI設計人員和您正在使用的特定實現的編碼人員都沒有「沒想過。我同意amarillion - OSGI是類沒有發現問題的噩夢,幾乎沒有可用的故障排除機制。最終用戶對於更多的部署靈活性可能是有價值的,但對開發人員來說卻是H H。 – user252690

+0

@ user252690匿名懦夫很容易在互聯網上謾罵。如果你冷靜下來並決定學習一些東西,你就會知道哪裏能找到合適的人來幫助你。 –

2

我認爲這裏的麻煩是你沒有指定你的包使用的正確的一組包/類(在你的MANIFEST中使用Import-Packages指令)。除非OSGi知道這些,否則它真的無法幫助!

不知道你如何構建你的OSGi包,但你應該看看Maven bundle plugin,它解決了明確指定Import-Packages(至少是編譯時)的問題。見http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages

+0

+1。只需添加:Maven Bundle Plugin基於Bnd,所以我在關於使用Bnd的回答中所說的一切也適用於Maven Bundle Plugin。如果您的構建版本目前不是基於Maven的,則無需遷移到Maven即可獲得此功能。 –

1

我不回答中心問題,但爲類似問題提供了我的解決方案。

就我而言,我有這個類的結構:

  • interface javax.script.ScriptEngineFactory
  • class pkga.A implements ScriptEngineFactory
  • class pkgb.B extends A

我的主要項目代碼是B類和這個擴展類A在一個依賴的罐子。使用

<Export-Package>pkgb.*</Export-Package> 

不足,我收到一個錯誤,抱怨缺少javax.script.ScriptEngineFactory。這很奇怪,因爲它是標準JDK 8的一部分,請注意包pkgb中的代碼沒有明確指定參考javax.script.*; Manifest作者可能不知道這個接口需要導出?

我發現這除了出口-package指令解決了這個問題

<Export-Package>pkgb.*,javax.script.*</Export-Package>