2014-05-19 77 views
16

更新2:因爲我的博客是有點死的聯繫得到了降低,所以你可以在這裏查看的文章:管理OSGi的依賴地獄

https://www.dropbox.com/s/xvobgzqnl43kcda/Managing_OSGi_Transitive_Dependencies__Part_1____CitizenRandom.pdf?dl=0

https://www.dropbox.com/s/0bdooux4yhrf8lf/Managing%20OSGi%20Transitive%20Dependencies%20%28...pdf?dl=0

https://www.dropbox.com/s/km3mxqah6oy23iq/Why%20using%20Require-Bundle%20is%20a%20bad%20pract...pdf?dl=0

https://www.dropbox.com/s/mtenchtjopcrmr8/How%20many%20ways%20can%20we%20import%20bundles%20in%20OSGi_%20_%20CitizenRandom.pdf?dl=0

https://www.dropbox.com/s/sldxynx3fl8vn61/Managing%20OSGi%20Transitive%20Dependencies%20%282...pdf?dl=0

我有一個Maven項目,用我的pom.xml配置以下列方式非常有名的菲利克斯的Maven插件捆綁:

<packaging>bundle</packaging> 

(...) 

<plugin> 
      <groupId>org.apache.felix</groupId> 
      <artifactId>maven-bundle-plugin</artifactId> 
      <extensions>true</extensions> 
      <configuration> 
       <instructions> 
        <Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName> 
        <Bundle-Version>${project.version}</Bundle-Version> 
        <Export-Package>jlifx.*</Export-Package> 
        <!-- <Embed-Dependency>*</Embed-Dependency> --> 
       </instructions> 
      </configuration> 
     </plugin> 

然後,我有一些一階/包括水平依賴於我的POM以及:

<dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>4.11</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.commons</groupId> 
     <artifactId>commons-lang3</artifactId> 
     <version>3.1</version> 
    </dependency> 
    <dependency> 
     <groupId>commons-io</groupId> 
     <artifactId>commons-io</artifactId> 
     <version>2.4</version> 
    </dependency> 
    <dependency> 
     <groupId>commons-logging</groupId> 
     <artifactId>commons-logging</artifactId> 
     <version>1.1</version> 
    </dependency> 
    <dependency> 
     <groupId>io.netty</groupId> 
     <artifactId>netty-all</artifactId> 
     <version>5.0.0.Alpha1</version> 
    </dependency> 
</dependencies> 

現在我的問題開始......如果我做MVN安裝我將得到我的包以及其很好的MANIFEST.MF和所有的包,但我不會得到其他依賴包,這意味着如果我抓住我的包文件並將其放在OSGi框架實例上,我將獲得類似「無法解決1.0:缺少需求[1.0] osgi.wiring.package; (&(osgi.wiring.package =等等......」

所以我發現我創建第1級依賴捆綁一個辦法就是像這樣在我的POM創建一個配置文件:

<profiles> 
    <!-- http://www.lucamasini.net/Home/osgi-with-felix/creating-osgi-bundles-of-your-maven-dependencies --> 
    <!-- -Pcreate-osgi-bundles-from-dependencies bundle:wrap --> 
    <profile> 
     <id>create-osgi-bundles-from-dependencies</id> 
     <build> 
      <directory>${basedir}/bundles</directory> 
      <plugins> 
       <plugin> 
        <groupId>org.apache.felix</groupId> 
        <artifactId>maven-bundle-plugin</artifactId> 
        <version>2.0.1</version> 
        <extensions>true</extensions> 
        <executions> 
         <execution> 
          <id>wrap-my-dependency</id> 
          <goals> 
           <goal>wrap</goal> 
          </goals> 
          <configuration> 
           <wrapImportPackage>;</wrapImportPackage> 
          </configuration> 
         </execution> 
        </executions> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 
</profiles> 

這樣當我執行mvn -Pcreate-osgi-bundles-from-dependencies bundle:wrap我會得到捆綁,構造良好並且工作正常但是,這裏就是真正的交易,這些捆綁還依賴於他們需要將他們的依賴包裹在一起,根據很多網頁,很久以前我們有了mvn org.apache .felix:maven-bundle-plugin:bundleall目標是爲我們做到這一點,但我試過了,它是buggy並且返回異常,並且它被標記爲不推薦使用,根據Stuart的說法,它將在maven 2.4.1中被移除並且稍後(參考:https://issues.apache.org/jira/browse/FELIX-4145)。

所以,我唯一的解決辦法,現在是,手動,檢查我的第一級依賴每個清單和去谷歌包含所需的軟件包的罐子,將它們添加到我的pom.xml作爲Maven依賴,然後運行mvn -Pcreate-osgi-bundles-from-dependencies bundle:wrap將它們打包爲捆綁包。

這就是被稱爲依賴地獄......

有什麼辦法來自動解決第n水平依賴於一個maven束的OSGi項目的這項任務?即讓Maven研究我的第一級依賴關係的清單文件,閱讀導入包,查看提供此類包的jar的中央回購站,下載它們並將它們打包爲捆綁包?

注意:請提供有關如何實現此目的的詳細說明,請不要鏈接到此工具或可以解決此問題的工具。這些工具的主要問題是缺少示例和文檔。例如bundleall已被棄用,但似乎沒有工具可以取代它,至少在maven bundle插件的官方文檔中,到目前爲止已棄用... 我確定我可能已經穿過工具能夠做到這一點,但缺乏文件禁止新手用戶知道...

謝謝!





編輯-1:

謝謝您的回答至今:) 我覺得我沒有解釋以最適當的方式我的情況我只是通過純文本來完成這些工作,我感到有些困難。或者,也許我不明白你的答案。我在OSGi中頗爲「全新」,我唯一的知識來自書籍(OSGi in Action等)和Google。

想象一下,我的包導入包A和包B.但包A導入包C,而包B也導入C.但是現在C進口包裝D,E,F和G.另一方面,包裝D進口一噸其他包裝,E,F和G也是如此。

我的電腦中只有我自己的包裝以及提供程序包A和B的軟件包,因爲它們是我的第一級依賴項。不過,我沒有其他必需的捆綁包,即使它們作爲jar安裝在我的JDK安裝文件夾中,我也沒有將它們作爲捆綁包捆綁,甚至我也不知道我可以從哪裏獲得jar來包裝它們(其實我知道,但讓我想象我不)。

我期望構建工具做的是運行類似以下的算法:

1)轉到我的包MANIFEST.MF和讀取進口包裝領域。枚舉所有必需的包和它們的響應。版本。

2)在互聯網上的某個地方搜索我需要的圖書館的罐子或包。

3)下載每一個和檢查,如果他們只是普通的罐子或有一個有效的OSGi清單文件(即它們是捆綁)

3.1)如果他們是捆綁,複製他們到我的包/文件夾。

3.2)其他包裝罐子到使用任何工具來做到這一點和包複製到我的包/文件夾束。

4)現在,對於每個下載/創建的新捆綁包,重複步驟1),2),3)和4)。

我想作爲最終結果是什麼:一種,而我有直接或間接的依賴,這樣我就可以將它們安裝在我的OSGi框架實例上的飛,如費利克斯或每個庫包春分。

我不想要什麼:

1)必須手動做到這一點,因爲如果我嘗試解決依賴我可花了幾個小時或幾天收集和包裝瓶的每個依賴性。

2)將所有依賴嵌入到ubber/mega包中。根據我讀過的幾本書,這是一個糟糕的做法,單獨維護每個依賴項很困難,而且還會破壞模塊化。

注:我的問題是不是包裝罐成捆的特定任務,而是遞歸地做這件事,以每捆的進口,即使他們需要從在線存儲庫下載,如Maven的中央。

有沒有辦法自動做到這一點,或者我失去了一些關於OSGi的東西?這麼大,我永遠不需要這樣做,我要求?

EDIT 2:

一些,如果不是全部,進口軟件包的相關性,可以在運行時解決。想象一下,OSGi框架試圖啓動一個捆綁包,而不是顯示「無法解析8.0:缺少需求[8.0] osgi.wiring.package;」的錯誤消息它會在網上搜索該軟件包,下載並在運行中進行安裝。生活會容易得多。

+1

如果我正確理解你的話,你想要在內部構建包含很多依賴關係的包?你可能知道osgi錯了嗎?如果您想將完整的應用程序打包到檔案中,您可以創建一個EBA,並使用useTransitiveDependencies = true來包含所有3.方庫。 –

+0

嗨,不,我不想將它們全部打包在一個存檔中(archive = .jar文件是否正確?)。我只想讓maven爲我的項目的每個傳遞依賴關係生成一個包歸檔。理想情況下,他會閱讀我的軟件包的導入包字段,列出軟件包名稱和版本,轉到maven的中央存儲庫,從那裏獲取所需的庫,將不包含的包包裝到捆綁包中,然後將它們粘貼到我的項目文件夾中。然後對每個傳遞依賴關係都做同樣的事情。 – PedroD

+0

我想你是在誤解一個包是什麼。 bundle是一個包含所有特定類的容器,其他包(包括版本或版本範圍)和導出語句的導入語句。你可以將你所有的三方庫如commons-lang,commons-io等應用到你的應用程序並導入必要的語句。即使3. party libs有你需要在你的bundle中覆蓋的靜態字段,你也沒問題,因爲在OSGi中,每個bundle都有它自己的類加載器。 –

回答

3

使用maven-bundle-plugin中的條件包以遞歸方式將JAR包中的所有必需包內聯並激活標記true。

+0

你能否請你發佈你的解決方案@PedroD,我感興趣:) – reyman64

5

如果你想包裝不是捆綁的罐子,而只是需要這些罐子作爲OSGi框架中的庫,你可以用BND工具包裝它。看到鏈接How to create/generate OSGi bundles from existing third-party jars?

但我可以看到你使用非常常見的libaries,已經被轉換爲osgi包。您可以在SpringSource Enterprise Bundle Repository中找到許多轉換爲捆綁的庫。

但是,如果您找不到任何未轉換爲良好OSGi包的庫,則可以使用PAX-URL中的WRAP協議在OSGi框架中安裝這些依賴關係。要使用這些協議取決於您正在使用的OSGi框架,但在默認情況下安裝在apache karaf中。例如,爲了從行家庫安裝庫:

[email protected]> osgi:install -s 'wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&Bundle-Version=2.4' 

此指令從安裝Maven倉庫公地琅庫到OSGi框架和將其包裝成OSGi包與所述首標中出現的行。

對於像你在第二次編輯中所說的自動安裝依賴關係,有幾種解決方案,但是有一點工作。有兩種主要的解決方案可以自動配置到OSGi框架,即「Felix OBR存儲庫」和「Felix Provisioning」捆綁軟件和Equinox p2存儲庫。他們都有控制檯命令來自動安裝捆綁和功能。問題是,我實際上找不到一個好的公共捆綁軟件包。您需要使用所有捆綁包構建您自己的存儲庫,而不是您需要的。

如果您使用maven-bundle-plugin,當您將工件安裝到本地maven資源庫中時,插件會更新文件「repository」。XML」位於你的資料庫,以反映的根本要求和你捆綁的能力這個文件是一個OBR庫文件

+0

閱讀此:http://stackoverflow.com/questions/how-to-ask –

+0

嗨,感謝您的幫助! 是的,我知道有幾種工具可以幫助我將jar文件打包成捆。我的問題比這個更大。我編輯了我的開篇文章(請參閱下面的文章),試圖解釋我的問題。 再次感謝! – PedroD

3

我想作爲最終結果:A每個庫包,而我 有直接或間接的依賴,這樣我就可以 安裝他們即時在我的OSGi框架實例,如費利克斯或秋分。

好吧,如果我正確地理解你的問題,你想要的東西一樣maven-dependency-plugin?

 <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-dependency-plugin</artifactId> 
      <executions> 
       <execution> 
        <id>copy-dependencies</id> 
        <phase>package</phase> 
        <goals> 
         <goal>copy-dependencies</goal> 
        </goals> 
        <configuration> 
         <outputDirectory>${project.build.directory}/thridparty-libs</outputDirectory> 
         <overWriteIfNewer>true</overWriteIfNewer> 
         <includeScope>runtime</includeScope> 
         <excludeGroupIds>${project.groupId}</excludeGroupIds> 
         <excludeArtifactIds>...</excludeArtifactIds> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 

如果您遇到問題,您有很多沒有osgi-Manifest的依賴關係,您應該檢查它們是否可用於springsource企業軟件包存儲庫http://ebr.springsource.com/repository/和apache-servicemix軟件包http://search.maven.org/#search|ga|1|g%3A%22org.apache.servicemix.bundles%22(如我的評論中所述)

+0

這很接近,但仍不會使大部分工作自動化。 我認爲有一種方法可以配置OBR存儲庫來完成這項工作,我會在這裏發佈任何來自我方的更新,以便與任何感興趣的人分享我可以找到的解決方案。 謝謝! – PedroD

0

嘗試p2-maven-plugin它完全符合您從1到4所描述的內容。它實際上使用tycho來構建p2存儲庫,但您也可以使用它來收集和捆綁您的依賴關係和傳遞依賴關係。 我不寫這裏的例子,因爲在上面的鏈接每一個想法都很好地記錄在一個簡單的理解方式的例子。

希望這有助於

0

此功能包括:文件夾中的罐子您的罐子依賴關係:OSGI-INF/lib目錄/

在的build.gradle:

**

dependencies { 
    ...dependencies 
} 
def bundleClassPath() { 
    def list = [] 
    configurations.compile.each { 
     list += 'OSGI-INF/lib/' + it.name 
    } 
    return list.join(',') 
} 
def includeResource() { 
    def list = [] 
    configurations.compile.each { 
    list += 'OSGI-INF/lib/' + it.name + "=" + it.path 
    } 
    return list.join(',') 
} 
bundle { 
    instructions << [ 
    'Bundle-ClassPath' : bundleClassPath(), 
    '-includeresource' : includeResource() 
    ] 
} 

**