OSGi:通过程序决定是否可以启动bundle



上下文

我有一个基于OSGi的大型应用程序(Equinox 3.9/Eclipse RCP 4.4),其中包含一些"可选"捆绑包。这些可选捆绑包中的每一个都提供了可选的用户界面和一些额外的服务(通过SCR组件),这些服务仅适用于我们的一部分客户。

该应用程序始终以预打包安装的形式分发(也就是说,我们既不使用P2,也不使用任何其他自动提供机制)。直到最近,我们为每个需要一些可选捆绑包的客户构建了不同的预打包安装。可选捆绑包的数量正在增加,要构建的自定义预打包安装的数量也在增加。

因此,我们只想构建一个交付给所有客户的安装包,其中包含所有可选捆绑包,然后在运行时决定启动哪些可选捆绑包。但问题是:只有在用户通过服务器进行身份验证后,才知道要启用的一组可选功能。也就是说,一些最终用户可以访问多个帐户,每个帐户都可以访问要启用的一组不同的可选功能。因此,在用户登录之前,可选捆绑包必须保持不可用,然后,只加载允许的可选捆绑包。由于这些可选捆绑包通过各种扩展程序(Eclipse的插件注册表、SCR和蓝图)做出贡献,这意味着在确定它们确实被授权启动之前,不得允许可选捆绑包达到RESOLVED状态。当用户登录和注销特定的服务器帐户时,还必须能够加载和卸载这些可选捆绑包。

潜在的解决方案和问题

我已经确定了一些潜在的解决方案,但每一个都有尚未解决的问题。因此,我只需要对以下任何一种情况的所有问题做出正确的肯定回答。

  1. 可选捆绑包需要一些"启用"功能我认为这将是最干净的方法。可选捆绑包会添加类似"Require capability:com.acme.optionalfeatures;identifier=my custom feature identifier"的内容。在运行时,该功能将保持未解析状态,直到用户获得身份验证,因此扩展程序将自动忽略该捆绑包。一旦注册了启用功能,捆绑包就会自动更改状态。太好了。但以下是缺失的部分:a)如何注册新功能命名空间b)我可以动态更改捆绑包提供的功能吗?如果可以,我该如何更改?c) (如果(b)不可能)我可以动态注册具有新功能的新"资源">吗?如果可以,我该如何注册?

  2. 让可选捆绑包导入一些"启用"包这是上一个场景的变体,可能比自定义功能命名空间更容易管理。。。这些"启用包"可以通过"动态创建"的包而存在。也就是说,一些管理器捆绑包会使用ByteArrayInputStream调用BundleContext#installBundle(String,InputStream),返回包含Manifest的动态生成的捆绑包存档。出口适当"启用包"的MF。听起来很简单,但工具链中的几个组件(IDE、PDE、P2、产品导出…)会抱怨这些必需的包不存在。为了避免这些问题,需要在安装到框架中时动态添加require包标头。但是有没有任何机制可以让bundle的头文件在这么早的时候(也就是说,一旦bundle安装到框架中)被更改Class Weaving在此不适用。

  3. 可选捆绑包都需要一个单独的启用包(都一样),这确实存在然后,当可选捆绑包尚未获得授权时,Resolve Hook将从潜在的布线候选中过滤出导出该包的捆绑包。但是以后如何请求重新考虑所有捆绑包,以便在用户登录或注销时进行解决

排除的解决方案

以下解决方案已被排除在外:

  • 将可选捆绑包放在不同的目录中,然后使用BundleContext#installBundle(…)来启用这些捆绑包。尽管此解决方案在部署时确实有效,但它给开发带来了巨大的负担(因为相对于工作区、本地git配置、测试环境等,捆绑包位于某个难以预测的文件夹中,因此无法正确构建要提供给#installBundle的位置)。打包过程也变得更加复杂,因为我们首先需要分开这些可选的捆绑包,然后更新几个Equinox/P2配置文件,以防止他们找到这些现在丢失的捆绑包。

  • 通过条件性地从可选捆绑包的激活器抛出异常来防止其被激活。这根本无法解决我们的问题,因为期权捆绑包仍将被允许达到已解决状态,因此能够通过中间扩展器进行贡献。

  • 使用P2在运行时安装新功能。这里的问题是,通过P2 1)对捆绑包列表所做的更改本质上是持久的(这意味着可选功能将在下次发布时自动重新启用),2)需要重新启动框架才能正确完成。

注意:我们对这些额外捆绑包实际分发给不需要它们的用户这一事实没有"安全"相关的担忧。我知道用户可能很容易破解安装程序,以强制启动一些可选的捆绑包。这并不构成重大问题。

您可以创建和安装一个捆绑包,该捆绑包提供可选捆绑包所需的功能或包。这将使它们能够得到解决。

但我不明白当多个用户以不同的权限访问服务器时,您的模型将如何工作。特权更高的用户会导致可选捆绑包"激活",因此这些功能将可用于同时访问服务器的特权较低的用户。

最新更新