当前位置: 首页 > 知识库问答 >
问题:

OSGi:通过编程决定是否可以启动捆绑包

袁俊弼
2023-03-14

上下文

我有一个基于OSGi的大型(Equinox3.9/EclipseRCP4.4)应用程序,还有几个“可选”包。这些可选捆绑包中的每一个都提供了可选的用户界面和一些额外的服务(通过SCR组件),这些服务只适用于我们的一部分客户。

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

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

潜在的解决方案和问题

我已经确定了一些潜在的解决方案,但对每一个都有悬而未决的问题。所以我只需要对以下任何一个场景的所有问题有正确的肯定答案。

>

  • 有可选的包需要一些启用功能。我认为,这将是最干净的方法。可选捆绑包会添加类似于“要求-能力:com.acme.optionalfeatures;标识符=my-Custure-特征-标识符”这样的内容。在运行时,该功能将保持未解决,直到用户被验证,因此扩展器将自动忽略该捆绑包。一旦启用功能被注册,包将自动更改状态。那太棒了。但以下是缺失的部分: a)如何注册新功能命名空间?b)我是否可以动态更改包提供的功能,如果可以,如何更改?c)(如果(b)不可能)我是否可以动态注册具有新功能的新资源,如果可以,如何注册?

    让可选的包导入一些“启用”包。这是上一个场景的变体,可能比自定义功能命名空间更容易管理...然后,这些“启用包”可以通过“动态创建”包而存在。也就是说,一些管理器包会调用BundleContext#InstBundle(String, InputStream),并带有ByteArrayInputStream,返回包含清单的动态生成的bundle归档。MF导出适当的“启用包”。听起来很简单,但是工具链上的几个组件(IDE、PDE、P2、产品出口...)会抱怨这些必需的包不存在。为了避免这些问题,需要在安装到框架中时动态添加必需包标头。但是,是否有任何机制允许在那么早的时候(即在捆绑包安装到框架中之后)更改捆绑包的头?类编织在这里不适用。

    所有可选的bundle都需要一个启用包(都是相同的),它确实存在。然后,当可选包尚未授权时,解析挂钩将从潜在的候选布线中过滤出导出该包的包。但是,当用户登录或注销时,我以后如何请求重新考虑所有捆绑包以解决问题?

    排除的解决方案

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

    >

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

    通过有条件地从其激活器中抛出异常,防止激活可选捆绑包。这根本不能解决我们的问题,因为仍然允许选项束达到已解决状态,因此能够通过中间扩展器做出贡献。

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

    注意:对于这些额外的捆绑包实际上分发给不需要它们的用户这一事实,我们并不担心与“安全”相关的问题。我知道用户可能很容易通过黑客攻击安装来强制启动一些可选捆绑包。这不构成重大问题。

  • 共有1个答案

    庄阿苏
    2023-03-14

    您可以创建并安装一个捆绑包,该捆绑包提供可选捆绑包所需的功能或包。这将使问题得以解决。

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

     类似资料:
    • 符号名ram 线程“main”组织中出现异常。奥斯基。框架BundleException:bundle ram[1]中未解析的约束:无法解析1.0:缺少需求[1.0]osgi。装电线。包裹(osgi.willing.package=android.dalvik)。阿帕奇。菲利克斯。框架菲利克斯。resolveBundleRevision(Felix.java:3826)位于org。阿帕奇。菲利克斯

    • 问题内容: 我需要以编程方式启动新的Java进程并动态设置JMX端口。所以不要这样做 我想做以下 但这不起作用。知道为什么吗? 问题答案: 在调用代码时,您已经错过了配置jmxremote连接器的机会。 您需要做的是创建您自己的rmi注册表和JMXConnectorServer来侦听rmi调用并将它们传递给MBeanServer。

    • 问题内容: 在我的AEM项目的代码中看似无关紧要的更改之后,我的捆绑软件无法解决。检查日志后,我可以看到出现以下错误。 该项目在本地编译得很好,并且只有在容器尝试解决该捆绑包后,该问题才会出现。 我没有在任何更改中添加任何显式依赖项。项目对象模型与以前相同。顾名思义,这是一个核心Java软件包,因此我希望它会被System软件包公开。 我正在运行AEM支持的JDK 7,所以不要指望它与JVM兼容性

    • 我们使用Karaf-4作为OSGI容器。我们有几个与一个功能关联的捆绑包。当某个功能中的任何捆绑包失败时,我们希望以编程方式进行识别。我们尝试了 BundleTracker 和 BundleListener,但是当捆绑包在“GracePeriod”状态下等待失败时,我们不会收到通知。 我们可以在karaf控制台中使用“list”命令查看故障包的状态。我们希望通过通知以编程方式实现这一点,而不是在k

    • 当我得到一个Spring豆(通过getBean())时,有没有办法从java代码中验证豆子是否已经用范围=原型定义了? Spring配置: Java: sc 我可以实例化它两次并比较对象,但是我想避免不必要的对象创建。这个答案的反义词可能会有用:https://stackoverflow.com/a/9125610/156477

    • 我试图用bndool编写一个OSGI REST包。 我在cnf项目中添加了我需要的所有罐。然后我把它们添加到捆绑包构建路径中。 我得到以下运行时异常 OSGi捆绑包未启动:缺少需求osgi.wiring.package( 我不明白这个错误,因为我使用了javax.ws.rs-api 2.0.1。 我试图在构建路径中明确指定版本,如下所示 没有任何运气。 我用错罐子了吗? 非常感谢。 这是我的bnd