管理OSGi依赖地狱

Ped*_*roD 20 java dependencies osgi maven osgi-bundle

更新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>
Run Code Online (Sandbox Code Playgroud)

然后我的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>
Run Code Online (Sandbox Code Playgroud)

现在我的问题开始了...如果我做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>
Run Code Online (Sandbox Code Playgroud)

这样当我执行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的捆绑包,因为它们是我的第一级依赖项.但是我没有任何其他必需的捆绑包,即使它们作为jar安装在我的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;" 它会在线搜索该软件包,下载并即时安装.生活会变得如此简单.

Fer*_*con 6

如果你想包装不是捆绑的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'
Run Code Online (Sandbox Code Playgroud)

该指令将maven存储库中的commons-lang库安装到OSGi框架中,并将其包装为OSGi包,其中标题出现在该行中.

对于自动安装依赖性,就像你在第二次编辑中说的那样,有几个解决方案,但是有点工作.自动捆绑到OSGi framewor有两个主要的解决方案,即"Felix OBR存储库"和"Felix Provisioning"捆绑包以及Equinox p2存储库.它们都有控制台命令来自动安装捆绑包和功能.问题是,实际上我找不到一个好的捆绑包公共存储库.您需要使用所需的捆绑包构建自己的存储库.

如果使用maven-bundle-plugin,当您将工件安装到本地maven存储库时,插件会更新位于存储库根目录中的文件"repository.xml",以反映捆绑包的要求和功能.该文件是OBR存储库文件.


小智 4

使用 maven-bundle-plugin 中的 Conditional-Package 递归内联 JAR 包中所有必需的包并激活标签 true。

  • 您能否发布您的解决方案@PedroD,我很感兴趣:) (4认同)