Apache Karaf 中的特性、捆绑包、依赖项、先决条件和要求之间有什么区别?

What are the differences between features vs bundles vs dependencies vs prerequisites vs requirements in Apache Karaf?

不幸的是,名为 Karaf 的 OSGi 容器实现的文档很少。概念被刷掉,术语之间的关系没有建立。

我在阅读了 Karaf 开发人员撰写的文本后得出的结论(我猜?):

请填写。

这是我的 features.xml 示例,我 运行 通过 maven-resources-plugincopy-resources 目标,因此发生了 ${var} 的插值。

<?xml version="1.0" encoding="UTF-8"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.0.0 http://karaf.apache.org/xmlns/features/v1.0.0"
    name="special-server-features">

    <!-- Special Server -->
    <feature name="special-server" version="1.0.0" install="auto" resolver="(obr)">

        <details>
            A feature is just a group of bundles that should all be installed together.
            When an OSGi container adds a bundle, it goes through a resolution process
            to make sure that the bundle’s dependencies are met (and that it does not
            conflict with other installed bundles). However, that resolution process
            does not include any ability to obtain any dependencies; it just checks to
            see if they are available and delays or prevents the bundle from starting
            if a required dependency is missing.

            Requirements can tell the feature resolver to
            automatically install the bundles to satisfy the requirements.

            Dependencies vs. prerequisites:
        </details>



        <!-- Required feature repositories (containing all bundles) -->
        <repository>mvn:org.apache.camel.karaf/apache-camel/${camel.version}/xml/features</repository>
        <repository>mvn:org.apache.cxf.karaf/apache-cxf/${camel.version}/xml/features</repository>

        <bundle version="${camel.version}" prerequisite="true">camel-core</bundle>
        <bundle version="${camel.version}" prerequisite="true">cxf</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-blueprint</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-jackson</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-cxf</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-http</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-jaxb</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-jsch</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-log</bundle>
        <bundle version="${camel.version}" prerequisite="true">camel-stream</bundle>
    </feature>

</features>

Apache Karaf 文档基本上扩展了 OSGi 规范的术语,这意味着假设您对 OSGi 有一定的了解。

说到这里,你提到的不同术语在 OSGi 或 Karaf 中都可以清楚地找到。

术语“Bundle", "Dependency" and "Requirement”属于 OSGi 核心规范。而 "Feature" 和 "Prerequisite" 是 Apache Karaf 特定术语。

现在进入您的列表:

问:"prerequisite" 不允许我的 "special-server" 包在 OSGi 容器中不可用时启动我的 "special-server" 包。

A: 首先,请注意 "prerequisite" 不适用于捆绑包依赖项,仅适用于功能依赖项(顺便说一下,您的 XSD已经过时了,看看 current XSD), and yes, it is just a specialization of a dependency. For that, the documentation 是相当明确的:

If you will add prerequisite attribute to dependant feature tag then it will force installation and also activation of bundles in dependant feature before installation of actual feature.

问:依赖是一样的

A: 是也不是。由于 "prerequisite" 依赖项仍然只是对功能的 installation/activation 生命周期具有不同行为的依赖项,它们仍然只是描述依赖项但行为略有不同。

如果您改为引用包依赖项中的特殊属性,例如<bundle dependency="true">...,那么这意味着如果捆绑包(如果指定,则考虑可接受的版本)已经在系统中可用,它将不会再次安装。

问:这两个都不会导致 Karaf 自动获取并启动那些依赖项

A: 在这两种情况下,Karaf 都会根据需要安装相关功能和捆绑包。启动发生在之前(使用 "prerequisite" 功能)或在功能安装时(除非您已禁用它)。

问:根据文档,需求会导致 Karaf 自动获取并启动那些 dependencies/prerequisites/requirements.

A: 如果您指的是功能“requirements", then yes and no. Yes, because the resolver will try to find some other feature or bundle that provides the requirement (this is called a "Capability”,如果找到,请安装它。如果系统的当前状态已经提供了需求,则什么也不会发生,可以立即安装该功能。如果找不到与之对应的捆绑包或功能,则功能安装将失败。不会,因为它们不会立即启动。在功能本身启动时启动。

问:存储库在我的 features.xml 中,供开发人员知道从哪里获取 dependencies/prerequisites/requirements,但不会自动添加到 Karaf。

A: 显然没有。您添加存储库让 Karaf 解析器知道在哪里可以找到依赖特性的定义,而不是包。如果您对定义中的其他功能没有依赖性,则没有理由添加存储库。 documentation 提供了更多详细信息。

TL;DR

您是在抱怨文档,但您自己混淆了术语,因此您可能会得出错误的假设或期望。但我同意在一些细节上,Karaf 的术语可以更好更直观。

关于你的features.xml

  1. 请将架构更新为 v1.3.0
<features xmlns="http://karaf.apache.org/xmlns/features/v1.3.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="
            http://karaf.apache.org/xmlns/features/v1.3.0
            http://karaf.apache.org/xmlns/features/v1.3.0"
          name="special-server-features">
  1. 如果你想安装 Apache Camel 和 CXF,你只需安装功能,而不是包,例如:
    <feature name="special-server" version="1.0.0" install="auto" resolver="(obr)">
        <feature>camel-blueprint</feature>
        ...
    </feature>
  1. 您对 <bundle> 依赖项的声明完全错误。您指定的是功能,而不是捆绑包。
  2. <bundle> 标签没有 prerequisite 属性,而且从来没有(请遵守 XSD)
  3. <repository>只能在顶层声明,不能在特性内部声明(也违反了XSD)

示例功能存储库

根据您的示例,我编译了一个包含评论的示例功能存储库,以试图更实际地澄清问题:

<?xml version="1.0" encoding="UTF-8"?>
<features xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.4.0 http://karaf.apache.org/xmlns/features/v1.4.0"
    name="special-server-features">

    <!-- Required feature repositories -->
    <!-- We don't need to define this since Apache Camel already does it
    <repository>mvn:org.apache.cxf.karaf/apache-cxf/3.3.1/xml/features</repository>
    -->
    <repository>mvn:org.apache.camel.karaf/apache-camel/3.0.0.M2/xml/features</repository>

    <!-- Special Server -->
    <feature name="special-server" version="1.0.0" install="auto">
        <!--
            Require Java 8 at least.
        -->
        <requirement>osgi.ee;filter:=&quot;(&amp;(osgi.ee=JavaSE)(version&gt;=1.8))&quot;</requirement>

        <!--
            Every <feature> declares a dependency to another feature declaration
            (either available in this <features> repository or an external one.

            The dependency is bascially made up by referencing the "name" of
            another <feature> declaration.

            dependency="true"
                the feature will not be installed if already available

            prerequisite="true"
                the feature will be installed before ours and all bundles will
                be started
        -->
        <feature dependency="true" prerequisite="true">cxf</feature>
        <feature prerequisite="true">camel-core</feature>
        <feature prerequisite="true">camel-cxf</feature>

        <!--
            These features will just be installed as part of installing the
            current feature.
        -->
        <feature>camel-blueprint</feature>
        <feature>camel-jackson</feature>
        <feature>camel-http4</feature>
        <feature>camel-jaxb</feature>
        <feature>camel-jsch</feature>
        <feature>camel-stream</feature>

        <!--
            Every <bundle> declares a dependency to a standard OSGi Bundle using
            a URL including a protocol to uniquely identify the artifact.

            For Apache Karaf the most common protocol is to rely on Maven:
            https://ops4j1.jira.com/wiki/spaces/paxurl/pages/3833866/Mvn+Protocol

            Here, you also need to know that Apache Karaf also provides an
            internal Maven repository which is asked first and contains all
            Bundles that are already installed. This Maven repository usually
            exists at the Karaf installation sub-directory "system".
        -->

        <!--
            This bundle needs to be available, but we certainly don't want to
            "wrap" it again if it is already there.

            See also: https://ops4j1.jira.com/wiki/spaces/paxurl/pages/3833898/Wrap+Protocol
        -->
        <bundle dependency="true">wrap:mvn:org.minidns/minidns-core/0.3.3</bundle>

        <!--
            Now this is our own bundle which requires all of the above to do
            it's work properly.
        -->
        <bundle>mvn:com.mycorp.servers/special-server/1.0.0</bundle>
    </feature>
</features>