2012-02-15 191 views
7

我現在開始使用OSGi,iPOJO和iPOJO註解,並嘗試構建一個簡單的組件以在Felix中部署。不幸的是,我陷入了各種需要幾小時才能解決的問題,或者在浪費時間之後我甚至無法解決的各種問題,如下所示:Maven構建OSGi時出現的問題,包括依賴關係

我想使用我們使用Maven構建的OSGi包中的現有庫。該圖書館目前不是「OSGI-ified」,我們在中期內不打算這樣做。正因爲如此,我想包括這個庫及其所有的捆綁依賴,使用...:

<Embed-Dependency>*</Embed-Dependency> 
<Embed-Transitive>true</Embed-Transitive> 

什麼我現在,是OSGi的組件以下pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>foo</groupId> 
    <artifactId>samplecomponent</artifactId> 
    <packaging>bundle</packaging> 
    <version>0.0.1-SNAPSHOT</version> 
    <build> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <compilerArgument>-Xlint:all</compilerArgument> 
        <showWarnings>true</showWarnings> 
        <source>1.6</source> 
        <target>1.6</target> 
        <compilerArguments> 
         <encoding>UTF-8</encoding> 
        </compilerArguments> 
        <showDeprecation>true</showDeprecation> 
        <verbose>true</verbose> 
        <encoding>UTF-8</encoding> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.felix</groupId> 
       <artifactId>maven-bundle-plugin</artifactId> 
       <extensions>true</extensions> 
       <version>2.3.6</version> 
       <configuration> 
        <instructions> 
         <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> 
         <Embed-Dependency>*</Embed-Dependency> 
         <Embed-Transitive>true</Embed-Transitive> 
         <Embed-Directory>lib</Embed-Directory> 
         <Export-Package>*</Export-Package> 
         <_exportcontents>*</_exportcontents> 
        </instructions> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.felix</groupId> 
       <artifactId>maven-ipojo-plugin</artifactId> 
       <version>1.6.0</version> 
       <executions> 
        <execution> 
         <goals> 
          <goal>ipojo-bundle</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
    </build> 
    <dependencies> 
     <dependency> 
      <groupId>org.apache.felix</groupId> 
      <artifactId>org.apache.felix.ipojo.annotations</artifactId> 
      <version>1.8.0</version> 
      <scope>provided</scope> 
     </dependency> 
     <dependency> 
      <groupId>foo</groupId> 
      <artifactId>mylibrary</artifactId> 
      <version>1.2.3</version> 
      <scope>compile</scope> 
     </dependency> 
    </dependencies> 
</project> 

束jar文件是建立沒有任何問題,但部署和Apache的菲利克斯開始包的時候,我得到以下錯誤:

g! install file:/…/samplecomponent-0.0.1-SNAPSHOT.jar 
Bundle ID: 8 
g! start 8 
org.osgi.framework.BundleException: Unresolved constraint in bundle samplecomponent [8]: Unable to resolve 8.0: missing requirement [8.0] osgi.wiring.package; (osgi.wiring.package=com.sun.jdmk.comm) 

我已經設置了日誌級別到最高verbos不幸的是,沒有更多的信息。當我刪除mylibrary時,該軟件包將毫無問題地啓動。

任何建議表示讚賞!

回答

9

顯然,該庫使用com.sun.jdmk.comm,它並未從框架包中公開。您可以檢查this question,如果你真的需要它,或者投入額外的指示,從進口排除,

<Import-Package>!com.sun.jdmk.comm, *</Import-Package> 
+3

謝謝你,這是一般的好指針。但是,在添加排除之後,彈出了更多未解決的依賴關係。我現在所做的是將相關性設置爲「可選」: ' *; resolution:= optional' 現在我按預期工作:) – qqilihq 2012-02-15 13:18:32

+0

嗯,好看到你的問題已經解決了,但是'resolution:= optional'只能在遇到嚴重問題時使用:這樣做會破壞OSGi解析機制,因爲你將_every_ import標記爲可選項。我更喜歡'!com.sun。*,*'之類的東西。 – 2012-02-15 13:27:40

+0

好的,我將在未來記住這一點,感謝您的警告。但在上面的例子中,問題是,新的未解決的依賴關係出現在各種不同的命名空間中,造成一個巨大的排除列表。 – qqilihq 2012-02-15 13:32:56

4

如果你結束了一個巨大的排除列表,你應該把它看作一個標誌的東西不適合你的構建過程和包。

如果是我,我會做的第一件事是打開你的包並查看它包含的類,以及它導出的包。我懷疑你有一個非常大的包,這意味着你的包的依賴將會非常廣泛。這意味着你失去了OSGi的很多模塊化優勢,並且它也會導致很多實際問題。

任何時候你聲明一個包是可選的,你會說'我很高興接受這個包中類的ClassDefNotFoundExceptions。'對於你的代碼,你可能知道一個包是否真的是可選的,但要猜測第三方使用的包是可選的,這是相當棘手的。當然,這就是爲什麼預捆綁的罐子更方便,但我意識到這對你沒什麼幫助。 :)

通過嵌入第三方庫,你在做的是捆綁它,但以一種不可重複使用的方式。 (另一個區別是,它將與嵌入包共享一個類加載器,例如,如果第三方庫試圖通過反射加載你的類,那麼它可以使事情變得更好)。由於你在依賴方面存在問題,我傾向於加入一個包裝第三方jar的構建步驟,以便您可以清楚地看到哪些類和依賴關係與您的代碼相關,以及哪些屬於這個額外的jar。

我會看的另一件事是你的出口包= *子句。這將導出類路徑中的每個包,這意味着所有這些包都內置到您的jar中。你也可以得到他們所有的包裝進口。你可憐的軟件包變成了一個完整的應用程序,而不是你期望的精益OSGi模塊。你應該限制你的出口到最低限度(你想保持你的內部私人,你肯定不想分享其他人的內臟)。

-

企業OSGi的行動:http://www.manning.com/cummins

+0

感謝您的澄清。我已經將「出口包裹」縮小到必要的範圍。我沒有完全理解的是你的建議「[...]加入一個包裝第三方jar的構建步驟,這樣你就可以清楚地看到哪些類和依賴關係與你的代碼相關,以及哪些屬於這個額外的jar。 「 - 你能詳細解釋一下嗎? – qqilihq 2012-02-15 17:15:50

+0

有幾種方法可以做到這一點,但大多數使用maven bundle插件在封面bnd下使用的相同機制。 您可以下載bnd作爲命令行工具,然後使用可選的bnd文件調用'bnd wrap [yourjar]',以改進包名稱,導入和導出等內容。或者,你可以使用maven來做到這一點(谷歌'maven捆綁包的目標')。 這些應該都會給你帶來OSGi元數據的jar版本,很快就會給你帶來很大的麻煩。然後你可以看看裏面的內容,確認你只從jar中拖出了類,然後檢查包導入是否合理。 – 2012-02-15 19:01:07

+0

霍莉,對於遲到的回覆感到抱歉,並感謝您的提示。非常感激! – qqilihq 2012-03-06 16:49:27