簡體   English   中英

管理OSGi依賴地獄

[英]Managing OSGi Dependency Hell

更新2 :由於我的博客有點死,鏈接降級,所以你可以在這里查看文章:

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中配置的非常有名的felix maven bundle插件,方法如下:

<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中也包含一些1級/級別的依賴項:

<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 = etc ......”)

因此,我發現創建我的第一級依賴項包的一種方法是在我的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我將獲得捆綁包,構造良好並且正常工作。 但是,這是真正的交易。 這些bundle也有自己的依賴關系,因此他們需要將它們的依賴關系作為bundle捆綁在一起。 根據很多網頁,很久以前我們有mvn org.apache.felix:maven-bundle-plugin:bundleall目標為我們這樣做,但我已經嘗試過,它是錯誤的並且返回異常並且被標記為已棄用根據Stuart的說法,它將在maven 2.4.1及更高版本中刪除(參考: https//issues.apache.org/jira/browse/FELIX-4145 )。

因此,我現在唯一的解決方案是手動檢查我的第一級依賴項的每個清單,然后google查找包含所需包的jar,將它們作為maven依賴項添加到我的POM.XML中,然后運行mvn -Pcreate-osgi-bundles -from-dependencies bundle:wrap將它們包裝為bundle。

這就是所謂的依賴地獄......

有沒有辦法自動完成解決maven-bundle osgi項目的n級依賴項的任務? 即使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的捆綁包,因為它們是我的第一級依賴項。 但是我沒有任何其他必需的捆綁包,即使它們作為jars安裝在我的JDK安裝文件夾中,我沒有它們作為捆綁包,甚至我也不知道在哪里可以讓罐子包裝它們(實際上我知道,但讓我想象我沒有)。

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

1)轉到我的捆綁MANIFEST.MF並閱讀Import-Package字段。 枚舉所有必需的包及其resp。 版本。

2)在Internet上的某個地方搜索我所需庫的jar或包。

3)下載每個並檢查它們是否只是普通的罐子或有一個有效的osgi清單文件(即它們是一個包)

3.1) 如果它們是捆綁包則將它們復制到我的捆綁包/文件夾中。

3.2) 否則使用任何工具將jar包裝成一個包,並將包復制到我的包/文件夾中。

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

我想要的最終結果是:每個庫都有一個直接或間接依賴的bundle,這樣我就可以在我的OSGi Framework實例中即時安裝它們,比如felix或equinox。

我不想要的:

1)必須手動執行此操作,因為如果我嘗試解決依賴關系的每個依賴關系,我可能花費數小時或數天收集和包裝罐子。

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

注意:我的問題不是關於將jar包裝到一個包中的特定任務,而是關於遞歸地執行每個包的導入,即使它們需要從在線存儲庫(例如maven的中心)下載。

有沒有辦法自動執行此操作,或者我錯過了一些關於OSGi的大事? 如此之大,我永遠不需要這樣做,我要求的?

EDIT 2:

一些(如果不是全部)Import-Package依賴項可以在運行時解決。 想象一下OSGi框架嘗試啟動一個包,但不顯示錯誤消息“無法解析8.0:缺少需求[8.0] osgi.wiring.package;” 它會在線搜索該軟件包,下載並即時安裝。 生活會變得如此簡單。

如果你想包裝不是捆綁的jar,但只需要將這些jar作為捆綁包作為OSGi框架中的庫,你可以用BND工具包裝它。 請參閱如何從現有第三方罐創建/生成OSGi包的鏈接

但我可以看到你使用非常常見的庫,而不是已經轉換為osgi包。 您可以在SpringSource Enterprise Bundle Repository中找到許多轉換為bundle的

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

root@karaf> osgi:install -s 'wrap:mvn:commons-lang/commons-lang/2.4$Bundle-SymbolicName=commons-lang&Bundle-Version=2.4'

該指令將maven存儲庫中的commons-lang庫安裝到OSGi框架中,並將其包裝為OSGi包,其中標題出現在該行中。

對於自動安裝依賴性,就像你在第二次編輯中說的那樣,有幾個解決方案,但是有點工作。 自動捆綁到OSGi framewor有兩個主要的解決方案,即“Felix OBR存儲庫”和“Felix Provisioning”捆綁包以及Equinox p2存儲庫。 它們都有控制台命令來自動安裝捆綁包和功能。 問題是,實際上我找不到一個好的捆綁包公共存儲庫。 您需要使用所需的捆綁包構建自己的存儲庫。

如果使用maven-bundle-plugin,當您將工件安裝到本地maven存儲庫時,插件會更新位於存儲庫根目錄中的文件“repository.xml”,以反映捆綁包的要求和功能。 該文件是OBR存儲庫文件。

我想要的最終結果是:每個庫都有一個直接或間接依賴的bundle,這樣我就可以在我的OSGi Framework實例中即時安裝它們,比如felix或equinox。

好吧,如果我正確理解你的問題,你想要像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的依賴項,你應該檢查它們是否在springource enterprise bundle repository http://ebr.springsource.com/repository/和apache-servicemix bundle中可用。 http://search.maven.org/#search|ga|1|g%3A%22org.apache.servicemix.bundles%22 (如我的評論中所述)

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

嘗試p2-maven-plugin它完全按照你所描述的1到4進行操作。它實際上使用tycho來構建p2存儲庫,但你也可以使用它來收集和捆綁你的依賴項和傳遞依賴項。 我不是在這里寫例子,因為在上面的鏈接中,每個思考都有很好的文檔記錄,以便於理解。

希望這可以幫助

這個函數包括jar文件夾中的jar依賴項: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()
  ]
}

**

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM