部署 OSGi 包会启动另一个包

Deploying OSGi bundle starts another one

我在 Felix 中部署了一个用于 Sling 的 OSGi 包 (BundleA)。该包加载初始 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 的激活器。因此,代码再次执行,我不希望那样。

我没有找到任何关于 "linked" 包的文档。但是我不熟悉 Felix/OSGi 所以我真的不知道要找什么。 BundleA 有 BundleB 有一个 Maven 依赖项,范围提供,因为它使用它的一些常量。不然我不知道他们两个能link干什么

关于什么可以触发另一个包的激活器的任何提示都将非常有助于理解它是如何工作的。如果需要,我可以 post 更多 code/info。谢谢

编辑:这是在使用 CI

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

用很短的话:

如果

,则启动捆绑包 (A)
  • 设置为自动启动,bundle的启动级别低于framework的启动级别
  • 另一个包 (B) 已启动,它使用包 A
  • 中的 classes

我猜你的 bundle B 使用了 Bundle A 的 classes,所以 Bundle A 将在 Bundle B 启动之前启动。

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

如果你想有更深入的理解,我建议你应该阅读第 4.3 章以及从这一 OSGi 核心规范链接的其他章节。

顺便说一句:我从来没有在我的任何项目中使用延迟启动策略或非启动包。如果你开始使用像声明式服务这样的组件模型,并通过 ConfigAdmin 使组件实例化逻辑基于配置,你可能不会再遇到这样的问题。您实际上没有必要实施 Bundle Activators。

编辑

根据问题中的新信息:

随着 Bundle B 的更新和 bundle 的刷新,Bundle A 被重新连接到 BundleB,然后再次启动。您应该考虑将 Bundle B 分成两个单独的包。一部分更恒定(例如:B-API),另一部分不是那个恒定(B-IMPL)。 Bundle A 应该只使用 B-API 并且当 B-IMPL 更新时你不会重新布线。

乍一看好像让你多干活,但这才是真正的逻辑分离。我们有很多包只包含 1-2 class 个文件,但它们很稳定并且很久没有新版本了。

我认为您不应该在捆绑包级别执行此操作。相反,您应该使用组件和服务。为此使用声明式服务 (DS)。

基本计划是:

  1. Component1 执行您在 Sling 中需要的任何资源的设置。当这一切都完成后,它发布一个服务...服务的类型并不重要,它可以只是一个没有方法的标记接口。

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

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

顺便说一句,如果你在Component1中做的任务很耗时,你不应该在组件的activate方法中同步做它们(或者在start方法中BundleActivator 就此而言!)。相反,您应该分拆一个线程并在那里执行它们。这避免了锁定 OSGi 事件系统和劫持属于启动器或另一个包的线程。