部署OSGi包启动另一个

时间:2016-02-24 09:16:48

标签: osgi apache-felix

我有一个用于Sling的OSGi包(BundleA),我在Felix中部署。此捆绑包加载初始Sling内容,然后通过激活器对此内容执行一些操作(设置权限和排序节点)。这很好用,我使用Felix maven-bundle-plugin构建它,并且我已经在激活器中放置了一个bundle事件监听器:

@Override
public void bundleChanged(BundleEvent event) {
  if (BundleEvent.STARTED == event.getType()) {
    logger.info("Bundle A has started");
    BundleContext context = event.getBundle().getBundleContext();
  }
}  

但我有另一个捆绑包(BundleB),在部署时,会以某种方式触发BundleA的激活器。因此,代码再次执行,我不想要。

我没有找到任何关于"链接"的文档。捆绑。但我不熟悉Felix / OSGi,所以我真的不知道该找什么。 BundleA具有一个Maven依赖项,提供范围,因为它使用了一些常量。否则,我不知道什么可以链接他们两个。

关于什么可以触发另一个捆绑包的激活器的任何提示都将有助于理解它是如何工作的。如果需要,我可以发布更多代码/信息。谢谢

编辑:这是在使用CI

时引发问题的循环
  1. 部署BundleB(sling-core):包含一个用于存储常量的枚举类
  2. 部署BundleA(sling-content):加载Sling初始内容,并使用激活器使用Jackrabbit API自动设置权限和排序节点。此代码使用存储在BundleA中的枚举。
  3. 重新部署BundleB(sling-core),因为推送了一些更改
  4. 问题:BundleA也重新启动,然后重新执行权限和节点排序,这是我不想要的

2 个答案:

答案 0 :(得分:1)

用很短的词:

如果

,则启动捆绑包(A)
  • 设置为自动启动,并且捆绑包的起始级别低于框架的起始级别
  • 启动另一个捆绑包(B),它使用捆绑包A中的类

我猜你的捆绑包B使用Bundle A中的类,所以Bundle A将在Bundle B启动之前启动。

您可能希望将Bundle A分为两个捆绑包。您可以创建一个仅包含Activator的新Bundle,因此当启动Bundle B时,这个新的Bundle将不会自动启动(因为这个新的Bundle中没有使用任何类)。

如果您想要更深入了解,我建议您应该阅读第4.3章以及从OSGi Core规范链接的其他章节。

顺便说一句:我从来没有在任何项目中使用延迟启动策略或非启动捆绑包。如果您开始使用像Declarative Services这样的组件模型并通过ConfigAdmin根据配置生成组件实例化逻辑,那么您可能不会遇到类似这样的问题。你真的没有必要实现Bundle Activators。

修改

根据问题中的新信息:

随着Bundle B的更新和捆绑包的刷新,Bundle A重新连接到BundleB,然后再次启动。你应该考虑将Bundle B分成两个独立的包。一部分更加恒定(例如:B-API),另一部分不是那么常数(B-IMPL)。 Bundle A应仅使用B-API,并且在更新B-IMPL时不会重新连接。

首先它似乎让你更多的工作,但这是真正的逻辑分离。我们有很多捆绑包,只包含1-2个类文件,但它们很稳定,很长一段时间没有新版本。

答案 1 :(得分:1)

我认为你不应该在捆绑级别这样做。相反,您应该使用组件和服务。为此使用声明性服务(DS)。

基本计划是:

  1. Component1执行Sling中所需资源的设置。当这一切都完成后,它会发布一个服务......服务的类型并不重要,它可能只是一个没有方法的标记界面。

  2. Component2在该服务上有强制引用(使用@Reference注释)。

  3. 现在,在服务可用之前,Component2不会激活。因此,在Component2的activate方法中,您确定已经正确设置了资源。

    顺便说一下,如果您在Component1中执行的任务非常耗时,则不应在组件的activate方法(或start方法中)同步执行这些任务。 {1}}就此而言!)。相反,你应该剥离一个线程并在那里做。这样可以避免锁定OSGi事件系统并劫持属于启动器或其他捆绑包的线程。