【问题标题】:OSGi: What's the difference between Import-Package/Export-Package and Require-Capability/Provide Capability?OSGi:Import-Package/Export-Package 和 Require-Capability/Provide Capability 有什么区别?
【发布时间】:2019-12-16 06:55:06
【问题描述】:

我目前正在使用 OSGi 框架,但我对一些我不是 100% 清楚的概念有疑问。我自己也在寻找它,但我找不到一个可以清楚解释它的体面答案。

在一个包中,他使用的清单头 ​​2 是 Import-PackageExport-Package。名称不言自明:对特定套餐的需求和对特定套餐的提供。为了获得那个包(或提供那个包),必须将完整的包安装在需要 Import 的框架中。

然后我们进入Requirements-Capabilities 模型的部分。这实际上可以与Import-PackageExport-Package 标题相同。这个Requirements-Capability 模型还有标题:Require-CapabilityProvide-Capability。这些再次代表要求某些东西和提供某些东西。

我知道Requirements-Capability 模型只是在后来的 OSGi 规范开发中才引入的。无法准确找到它的发布年份和版本。

但是,

  • 为什么要将此添加到规范中?我看不出它比 Import/Export-package 已经提供的更多:创建对其他包/捆绑包的依赖关系?

  • 谁能让我更好地理解这两组概念之间的区别(优缺点)?

【问题讨论】:

    标签: java osgi requirements capability


    【解决方案1】:

    当我们在 1998 年开始使用 OSGi 时,我们有一些明确的要求,但当然,并不清楚它会产生什么。所以我们开始明确地为我们拥有的需求和能力建模:包。 Import-Package 需要一种能力,而该能力由 Export-Package 提供。

    在 2003 年 Eclipse 想开始使用 OSGi,但他们需要一个工具来要求另一个包,他们不喜欢导出和导入所有包的想法。实际上,当时他们并没有看到包裹的好处。为了满足他们,我们添加了 Require-Bundle 和 Fragment-Host(他们的另一个愿望结果并不是那么好。)

    在我们使用这些扩展指定 OSGi 4.x 之后,我们开始考虑存储库,Richard 开发了 Oscar Bundle 存储库。使用 OSGi 4.0 中的新标头分析情况,很明显 Import-Package 的实现看起来很像 Require-Bundle,甚至类似于 Fragment-Host 处理。

    2006 年,Richard S. Hall 和我写了RFC 112,提出了一个更通用的模型,该模型捕获了现有依赖模型的语义,但并不特定于每个类型的需求。 IE。对于框架解析器,Import-Package 和Require-Bundle 仅在它们的命名空间 上有所不同。将 Import-Package 视为通用需求,将 Export-Package 视为通用功能,使得存储库模型非常简单。更好的是,它是可扩展的,因为我们总是可以添加更多的命名空间。这使得解析器完全独立于实际使用的命名空间。

    经过一些非常激烈的讨论,OSGi 核心平台专家组决定接受基本思想并制定需求和能力规范。尽管这最初是存储库的模型,但事实证明它对框架本身非常有用。因此,我们决定将现有规格调整到该模型。 OSGi 4.3 在内部将 Import-Package、Export-Package、Require-Bundle 等建模为 resource(捆绑包)的需求和功能。为了向后兼容,我们保留了现有的标头,但它们在内部被转换为需求和功能。

    最后回答你的问题。随着时间的推移,OSGi 规范添加了越来越多的命名空间。命名空间就像是需求和能力的type。它定义了该命名空间中 Capability 的一组属性的语义。 Requirement 是在这些属性上断言的过滤器表达式。 Resource 具有一组功能,当满足其所有要求时,这些功能会提供给运行时。 Resolver 的任务是找到一组彼此都满足的资源和运行时提供的能力。

    例如,我们添加了 osgi.ee 命名空间,它准确定义了捆绑包可以在哪些 VM 上运行。我们添加了 osgi.extender 命名空间,它模拟了对外部程序(如服务组件运行时 (SCR))的依赖关系。大多数 SCR 组件不需要 SCR 本身的任何封装,我们努力使它们尽可能独立。但是,除非运行时中的某些包提供 SCR 功能,否则 SCR 组件将毫无用处。请注意,这不能使用 Require-Bundle,因为 SCR 有多种实现。我认为大约有 20 个命名空间。每个命名空间都在 Namespace 类中定义。

    此模型为 OSGi 带来了许多优势:

    • 内聚力 尽管规范添加了许多命名空间,但解析器的实现从未改变过,因为它们适用于通用模型。
    • 细粒度 OSGi 包的独特之处在于它们以非常细粒度的方式描述它们的依赖关系。我知道的所有模块系统都倾向于使用不允许替换的简单模块到模块依赖关系。
    • 灵活 由于框架具体化了包之间的依赖关系,因此可以在运行时利用这些依赖关系。例如,在 OSGi enRoute 中,我将一个包链接到它的网页,遍历这些运行时连接。

    我个人认为 OSGi 的需求和能力模型是它最保守的秘密之一。据我所知,它可以用于许多领域,以将许多开发项目改进为软件工程领域。

    这个问题中唯一令人失望的部分是我认为我们在Core specification? 中已经很好地描述了这个问题? :-)

    【讨论】:

    • 感谢您为我解决这个问题。这正是我完全理解大局所需要的。我一直在阅读核心规范的部分内容,但需要处理大量信息并且有点失去了很好的概述。非常感谢!
    • 关于您的失望:OSGi 规范的最大缺陷是缺乏正是这种背景信息来提供对意图的洞察力、由于历史发展而导致的机制关系等。如何轻松编写的正面例子可读规范是许多 IETF RFC,例如 this one。介绍性的非正式部分为读者提供了背景知识和示例,以便于理解正式部分。试图掌握 OSGi,你只能通过像这样的贡献获得这种信息。
    • 我发现这是一个不公平的指控,因为这篇文章中提到的所有内容都在我链接的 OSGi 中,包括许多详细的图片。所有 OSGi 规范都是从背景信息开始的。然而,当我们写它的时候,我们经常被指责为规范如此复杂,因为它有太多的页面......这些东西之所以复杂是因为它不像熟悉的技术,而不是因为它没有很好的文档记录或具有某种固有的复杂性。
    【解决方案2】:

    requirements and capabilities 模型是导入/导出包模型的扩展。实际上,您可以将包导入表示为要求,将包导出表示为能力。

    导出/导入包允许松散耦合。您导出 API,客户端导入它。这样客户端只需要知道 API 就可以实现松耦合。

    在以后的阶段,当您将应用程序从捆绑包中组装出来时,这种松散的耦合会使流程自动化变得困难。

    如果您只是将客户端捆绑包提供给解析器,那么它只能自动发现您需要提供 API 的捆绑包。如果 API 的实现在不同的包中,那么解析器无法知道您需要它。

    这就是需求可以提供帮助的地方。让我们以HTTP Whiteboard model 为例。想要发布 servlet 的包需要导入 servlet api 包,但还需要表示它想要实现 osgi http 白板。

    这可以用 namespace="osgi.implementation", name="osgi.http", version="1.1.0" 的需求来表达。由于这很难手工编写,因此有注释支持。

    @HttpWhiteboardServletPattern("/myservlet")
    @Component(service = Servlet.class)
    public class MyServlet extends HttpServlet {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
                throws IOException {
            resp.getWriter().println("Hello");
        }
    }
    

    注解@HttpWhiteboardServletPattern 间接转化为上述要求。

    因此,当您使用此类构建捆绑包时,它将导入 servlet api 包,并且还需要 http 白板实现。

    现在,如果您查看像 felix http 服务这样的实现包,您会发现它为白板实现提供了功能。

    因此,如果您的捆绑包、servlet API 和 felix http 服务有一个 OSGi 存储库。然后,如果你只给它你的包,解析器就可以为你提供一个完整的应用程序。

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2020-06-10
      • 2018-07-05
      • 2017-10-30
      相关资源
      最近更新 更多