我有一个用于Sling的OSGi捆绑包(BundleA),我在Felix中部署了它。此捆绑包加载初始 Sling 内容,然后通过激活器对此内容执行一些操作(设置权限和对节点进行排序)。这很好用,我使用 Felix maven-bundle-plugin 构建它,并在激活器中放置了一个捆绑事件侦听器:
@Override
public void bundleChanged(BundleEvent event) {
if (BundleEvent.STARTED == event.getType()) {
logger.info("Bundle A has started");
BundleContext context = event.getBundle().getBundleContext();
}
}
但是我还有另一个捆绑包(捆绑包 B),在部署时,会以某种方式触发捆绑包 A 的激活器。因此,代码再次执行,我不希望这样。
我没有找到任何关于"链接"捆绑包的文档。但我不熟悉Felix/OSGi,所以我真的不知道要寻找什么。BundleA 具有 BundleB 具有 Maven 依赖项,提供了范围,因为它使用其中的一些常量。否则,我不知道是什么能把他们两个联系起来。
任何关于什么可以触发另一个捆绑包的激活器的提示都非常有助于理解它是如何工作的。如果需要,我可以发布更多代码/信息。谢谢
编辑:这是使用CI时引发问题的周期
- 部署捆绑包B(吊索核心):包含一个枚举类来存储常量
- 部署捆绑包A(sling-content):加载Sling初始内容,并使用激活器自动设置权限并使用Jackrabbit API对节点进行排序。此代码使用存储在捆绑包 A 中的枚举。
- 重新部署捆绑包B(吊索核心),因为推送了一些更改
- 问题:BundleA 还重新启动,然后重新执行权限和节点排序,这是我不希望的
用非常简短的单词:
在以下情况下启动捆绑包 (A)
- 设置为自动启动,捆绑包的起始级别低于框架的起始级别
- 启动另一个包 (B),它使用包 A 中的类
我猜您的捆绑包 B 使用捆绑包 A 中的类,因此捆绑包 A 将在捆绑包 B 启动之前启动。
您可能希望将捆绑包 A 分为两个捆绑包。您可以创建一个仅包含激活器的新捆绑包,因此当捆绑包 B 启动时,此新捆绑包将不会自动启动(因为此新捆绑包中没有使用任何类)。
如果你想有更深入的理解,我建议你应该阅读第4.3章以及OSGi Core规范中链接的其他一些章节。
顺便说一句:我从来没有在我的任何项目中使用过惰性启动策略或非启动捆绑包。如果您开始使用像声明性服务这样的组件模型,并通过 ConfigAdmin 基于配置创建组件实例化逻辑,您可能不再遇到这样的问题。您实际上没有必要实现捆绑激活器。
编辑
根据问题中的新信息:
当分发包 B 更新并刷新分发包时,分发包 A 将重新连接到分发包 B,然后重新启动。您应该考虑将捆绑包 B 分成两个单独的捆绑包。一部分更恒定(例如:B-API),另一部分则不是恒定的(B-IMPL)。捆绑包 A 应仅使用 B-API,并且在更新 B-IMPL 时不会重新布线。
首先,它似乎让你做更多的工作,但这是逻辑的真正分离。我们有许多仅包含 1-2 个类文件的捆绑包,但它们是稳定的,并且很长一段时间都没有新版本。
我认为你不应该在捆绑包级别这样做。相反,您应该使用组件和服务。为此,请使用声明性服务 (DS)。
基本计划是:
-
组件 1 执行您在 Sling 中所需的任何资源的设置。完成此操作后,它会发布一个服务...服务的类型并不重要,它可能只是一个没有方法的标记接口。
-
组件 2 在该服务上具有强制引用(使用
@Reference
注释)。
现在,在服务可用之前,组件 2 不会激活。因此,在组件 2 的activate
方法中,您确定资源已经正确设置。
顺便说一下,如果您在 Component1 中执行的任务很耗时,则不应在组件的activate
方法(或BundleActivator
的start
方法中同步执行它们!相反,您应该剥离一个线程并在那里执行它们。这样可以避免锁定 OSGi 事件系统并劫持属于启动器或其他捆绑包的线程。