如何正确地将 Spring 包含到 OSGified 包中

Posted

技术标签:

【中文标题】如何正确地将 Spring 包含到 OSGified 包中【英文标题】:How to properly include Spring into an OSGified bundle 【发布时间】:2012-06-10 13:01:55 【问题描述】:

我有一个非常简单的 OSGI 应用程序,它只监听注册/取消注册并向标准输出发送一些消息。

我的应用中有一个简单的 Spring 初始化 bean。我使用maven bundle插件将jar打包并放入felix。这是 pom 的摘录:

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.1.0.RELEASE</version>
        <type>jar</type>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>2.2.0</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Export-Package>org.spring.*</Export-Package>
                    <Bundle-Activator>foo.bar.Activator</Bundle-Activator>
                </instructions>
            </configuration>
        </plugin>
    </plugins>
</build>

项目编译得很好,可以很好地部署到Felix中,但是,当激活器被调用时,它会抱怨缺少这样的依赖:

bundle foo.bar.project [56] 中未解决的约束:无法 解决 56.0:缺少要求 [56.0] osgi.wiring.package; (&(osgi.wiring.package=org.springframework.context)(version>=3.1.0)(!(version>=4.0.0)))

我尝试改变这一行:

org.spring.*

对此:

*

其中 felix 抱怨 android-dalvik 不存在,所以我完全一无所知。

知道如何在不使用 Spring DM 的情况下将 Spring 包含在 OSGI 项目中吗?

编辑:这是生成的清单抱怨的内容(来自 Web 控制台)

导出的包

foo.bar.osgi foo.bar.service foobar.tracker

从 org.osgi.framework,version=[1.6,2) 导入的包 org.apache.felix.framework (0) org.osgi.util.tracker,version=[1.5,2) 来自 org.apache.felix.framework (0) 错误: org.springframework.context,version=[3.1,4) -- 无法解决 错误:org.springframework.context.support,version=[3.1,4) -- 不能 得到解决

清单标头 Bnd-LastModified:1339014840268

构建-Jdk:1.6.0_32

制作者:fooBar

Bundle-Activator: foo.bar.osgi.Activator

捆绑清单版本:2

捆绑名称:fooBar

Bundle-SymbolicName: foo.bar.OSGIProject

捆绑版本:0.20.0.SNAPSHOT

创建者:Apache Maven Bundle 插件

导出包:foo.bar.osgi.tracker;使用:="foo.bar.osgi.service, org.osgi.util.tracker, org.osgi.framework",

foo.bar.osgi;使用:="org.springframework.context.support, org.springframework.context, org.osgi.framework", foo.bar.osgi.service

进口包装:

org.osgi.framework;版本="[1.6, 2)", org.osgi.util.tracker; 版本="[1.5, 2)", org.springframework.context;版本="[3.1, 4)", org.springframework.context.support;版本="[3.1, 4)" 清单版本:1.0 工具:Bnd-1.15.0

这是我在 pom 中改变的时候

<configuration>
    <instructions>
        <Include-Resource>src/main/resources/spring-beans.xml</Include-Resource>
        <Bundle-Activator>nl.synovite.scheduled.osgi.Activator</Bundle-Activator>
        <Import-Package>*</Import-Package>></instructions>
</configuration>

【问题讨论】:

你能发布生成的 MANIFEST.MF 吗?为什么要导出“org.spring”?这是你代码库的包名吗? 我认为 org.spring.* 正在被导出,作为将每个 spring 依赖项重新打包到构建包中的一种方式。如果你必须在你的 bundle 中重新打包 spring(这实际上并不符合 OSGi 的模块化精神,imo), 可能比 更好。这至少避免暴露所有弹簧内部。 在这种情况下,私有包确实是一个更好的选择(实际上据我所知,大多数 OSGI 提供者在清单中都丢弃了私有包)。但是,无论是否私有,spring 根本没有打包到 jar 中。所以我继续在 felix 中添加所有 spring 依赖项作为 osgified 工件。 如您所说,私有包是构建指令而不是运行时指令。这避免了将构建问题与运行时行为混为一谈。 (请参阅下面我的回答,了解为什么两个指令包都没有弹出。) 【参考方案1】:

你在做

<Export-Package>org.spring.*</Export-Package>

但感兴趣的包是org.springframework.context。导出语法是一种模式,而不是完整的正则表达式,因此导出中的点实际上意味着点(即包分隔符),而不是任意字符。

<Export-Package>org.spring*</Export-Package>

应该做你想做的。

【讨论】:

我也试过这个,但后来它抱怨未解决的依赖关系。如果我将它们包括在内,它会抱怨更多未解决的依赖关系。我也尝试包含 *,但当然还有更多未解决的部门。所以我想我最好在 felix 中添加 osgified spring deps。 我同意使用预先存在的 osgified 包比尝试创建自己的包更好。当您导出 * 时,请查看您的捆绑包。您可能会惊讶于被拖入了多少。将整个类路径放在一个包中绝对不符合 OSGi 的精神!【参考方案2】:

好吧,我认为你的 bundle 基本没问题,但是 Felix 似乎无法解析 org.springframework 包,所以你需要添加一些导出 org.springframework 包的 bundle。我不太了解spring,但我想你可以从springsource下载那些包。

Maven 一定也找到了一个,因为它似乎能够编译它。

【讨论】:

问题是它确实编译了工件,但在生成的包中不包含 spring 库。如果我将库作为来自 springsource 的包添加,它似乎可以找到它们。奇怪,imo。 这可能会令人困惑,但要记住的是 Maven 管理构建时依赖项和 OSGi 运行时依赖项。 Maven 不知道如何或何时添加运行时依赖项,它只是创建一个捆绑包,如果它的依赖项也存在于运行时,它将起作用。

以上是关于如何正确地将 Spring 包含到 OSGified 包中的主要内容,如果未能解决你的问题,请参考以下文章

如何正确地将 JSON 字符串反序列化为包含另一个类的嵌套列表的类

如何正确地将 Kal 框架添加到我的 iPhone 项目中?

如何在 Spring 中有效地将排序的通量分组到序列化组中?

如何正确地将浮点指针从 C 库传递到其 C# 包装器

如何正确地将多个合并还原为远程主控

如何最好地将包含列表或元组的 Pandas 列提取到多个列中[重复]