Java 如何在OSGi中添加来自特定捆绑包版本的导入包

Java 如何在OSGi中添加来自特定捆绑包版本的导入包,java,osgi,aem,sling,Java,Osgi,Aem,Sling,我的项目有两个OSGi包(A和B),它们需要使用不同版本的javax。激活-A需要版本1.1.0,而B需要版本1.1.1 默认情况下,在AEM 5.6.1中,已经安装了一个捆绑包,该捆绑包导出了捆绑包a正在使用的版本1.1.1。为了让它使用1.1.0 instaed,我使用引导委派从JRE 7中获取javax.activation,用于1.1.0系统包。我正在使用AEM 5.6.1中的sling.properties文件进行设置 如果我在此sling.properties文件中给出的javax.

我的项目有两个OSGi包(A和B),它们需要使用不同版本的
javax。激活
-A需要版本1.1.0,而B需要版本1.1.1

默认情况下,在AEM 5.6.1中,已经安装了一个捆绑包,该捆绑包导出了捆绑包a正在使用的版本1.1.1。为了让它使用1.1.0 instaed,我使用引导委派从JRE 7中获取javax.activation,用于1.1.0系统包。我正在使用AEM 5.6.1中的sling.properties文件进行设置

如果我在此sling.properties文件中给出的javax.activation版本大于1.1.1,则a和B都使用系统版本(即使在
manifest.mf
文件中指定了导入包的版本);但是如果我给出的版本低于1.1.1,那么两个包都使用AEM提供的版本


如何配置捆绑包,以便使用不同版本的javax.activation从捆绑包B到捆绑包A?

由于OSGI捆绑包解析规则,这可能非常困难。看看这篇文章——我发现它很好地解释了各种适用的规则。具体来说,请查看
uses
指令:

如果有一种方法让两人使用相同的版本,生活就会简单得多(但我知道这可能并不总是可能的)

这是从上面的文章:

对于每个导入包声明,必须有 与同一包对应的导出包

捆绑包还可以将其他属性附加到它导入或删除的包 出口。如果我们在示例中添加了一个version属性,该怎么办

Bundle Name:Bundle导入包:org.apache.foo;version=“1.2.0”

这意味着,Bundle A依赖于包org.apache.foo和 1.2.0的最低版本。是的,你读对了。虽然有OSGI 如果不指定范围,但 与其使用固定版本,它将产生“最小值”的含义 具有固定值。如果有更高版本的相同 软件包,将使用更高版本。因此,捆绑包A无法解决问题 正确,除非有相应的捆绑包B导出 所需包装:

捆绑包名称:捆绑包B导出包:org.apache.foo;version=“1.2.0”

请注意,情况并非如此……如果捆绑包B导出了1.2.0版, 捆绑包A不需要指定版本1.2.0。它可以用这个 导入并解析即可:

捆绑包名称:捆绑包导入包:org.apache.foo

这是因为导入声明了它们需要的版本。出口的 版本未指定导入捆绑包必须使用的任何内容(其中 适用于任何属性,而不仅仅是版本)。进口包装规定 确切地说,它需要什么版本(或属性),以及相应的 必须存在具有相同属性的导出包

如果出现捆绑包a导入包的场景,会发生什么 它指定了由两个bundle提供的版本:

Bundle Name:Bundle导入包:org.apache.foo;version=“1.2.0”

捆绑包名称:捆绑包B导出包:org.apache.foo;version=“1.2.0”

捆绑包名称:捆绑包C导出包:org.apache.foo;version=“1.2.0”

bundle A使用哪一个bundle?答案是这取决于哪个 首先安装了捆绑包(B或C)。使用先安装的捆绑包 当多个包具有相同版本时满足依赖关系 被发现

在热部署捆绑包时,事情可能会变得更复杂一些 在一些已经解决之后。如果安装Bundle B呢 首先,然后尝试安装捆绑包A和以下捆绑包D 一起:

捆绑包名称:捆绑包D导出包:org.apache.foo;version=“1.3.0”

正如我们从上面看到的,Bundle A(1.2.0)中的版本声明 指1.2.0的最低版本;所以如果有更高的版本 然后,它会选择它(在本例中是Bundle D的1.3.0版本)。 然而,这给我们带来了捆绑包的另一个时间规则 解决方案:已解决的捆绑包具有更高的 未解决的优先顺序

原因是OSGI框架倾向于重用性 对于给定的束。如果解决了,新的捆绑包需要它,那么 不会尝试使用同一软件包的多个其他版本,如果 不需要。Bundle“uses”指令

以上关于束解析的规则仍然不够,并且 运行时仍可能使用错误的类,从而导致类强制转换 例外或类似情况。你能看到可能遗漏了什么吗

如果我们有这种情况呢。捆绑导出一个包, org.apache.foo,它包含一个类FooClass。FooClass有一个方法 返回类型为BarClass的对象,但未定义BarClass 在捆绑包的类空间中,它是这样导入的:

1、2、3、公共课{ 公共BarClass execute(){…}

Bundle Name:Bundle导入包:org.apache.bar;version=“3.6.0” 导出包:org.apache.foo;version=“1.2.0”

到目前为止,只要有另一包 正确导出具有正确版本的org.apache.bar

捆绑包名称:捆绑包B导出包:org.apache.bar;version=“3.6.0”

这两个捆绑包可以很好地解决问题。现在,如果我们再安装两个 捆绑包、捆绑包C和捆绑包D的外观如下:

捆绑包名称:捆绑包C导入包:org.apache.foo;version=“1.2.0”, org.apache.bar;version=“4.0.0”

捆绑包名称:捆绑包D导出包:org.apache.bar;version=“4.0.0”

我们可以看到Bundle C从Bundle导入了一个包org.apache.foo Bundle C可以尝试使用org.apache.foo中的FooClass,但是当它 获取返回值,该值是
Import-Package: javax.activation;version="[1.1.0,1.1.0]"
Import-Package: javax.activation;version="[1.1.1,1.1.1]"