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

1

7

It is unfortunate that the OSGi container implementation, called Karaf, is poorly documented. Concepts are brushed over, and relationships between terminology are not made.

My conclusions after reading the text authored by Karaf developers (I guess?):

  • "prerequisite" does not allow my "special-server" bundle to be started when other bundles (I would call dependencies) are not available in the OSGi container.

  • dependencies are the same

  • both of those don't cause Karaf to automatically fetch and start those dependencies

  • requirements, according to documentation https://karaf.apache.org/manual/latest/provisioning, will cause Karaf to automatically fetch and start those dependencies/prerequisites/requirements.

  • repositories are in my features.xml for developers to know where to get dependencies/prerequisites/requirements, but are not automatically added to Karaf.

Please fill me in.

Here is my example of a features.xml that I run through maven-resources-plugin's copy-resources goal so that interpolation of ${var}s occurs.

<?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>
Hypoglossal answered 29/3, 2019 at 7:10 Comment(0)
U
7

The Apache Karaf documentation basically extends the terminology of the OSGi specifications, which means it is assumed that you have some knowledge of OSGi.

Speaking of which, the different terms you mentioned can be located clearly in either OSGi or Karaf.

The terms "Bundle", "Dependency" and "Requirement" belong to the OSGi Core specification. Whereas "Feature" and "Prerequisite" are Apache Karaf specific terms.

Now to your list:

Q: "prerequisite" does not allow my "special-server" bundle to be started when other bundles (I would call dependencies) are not available in the OSGi container.

A: First of all, please note that the "prerequisite" does not apply to bundle dependencies, only to feature dependencies (btw. your XSD is outdated, have a look at the current XSD), and yes, it is just a specialization of a dependency. For that, the documentation is quite explicit:

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.

Q: dependencies are the same

A: Yes and no. As "prerequisite" dependencies are still just dependencies with a different behavior for the installation/activation life-cycle of a feature, they still just describe dependencies but behave slightly differently.

If you refer instead to the special attribute at a bundle dependency, e.g. <bundle dependency="true">..., then it means that if the bundle (respecting the acceptable version if specified) is already available in the system it will not be installed again.

Q: both of those don't cause Karaf to automatically fetch and start those dependencies

A: In both cases, Karaf does install dependent features and bundles as necessary. Starting happens either before (with "prerequisite" features) or at feature installation (unless you have disabled that).

Q: requirements, according to documentation, will cause Karaf to automatically fetch and start those dependencies/prerequisites/requirements.

A: If you are referring to feature "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") and install it if some is found. If the current state of the system already provides the requirement, nothing happens and the feature can be installed right away. If no bundle or feature can be found for that, the feature installation will fail. No, because they will no immediately be started. Starting happens when the feature itself is started.

Q: repositories are in my features.xml for developers to know where to get dependencies/prerequisites/requirements, but are not automatically added to Karaf.

A: Clearly no. You add repositories to let the Karaf resolver know where to find the definition of dependent features, not bundles. If you don't have dependencies to other features in your definition, there is no reason to add a repository. The documentation provides more details.

TL;DR

You are complaining about the documentation but you are mixing up terminology by yourself and by that you may end up in false assumptions or expectations. But I agree that in some details, the terminology of Karaf could be better and more intuitive.

Regarding your features.xml:

  1. Please update the schema to 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. If you want to install Apache Camel and CXF, you just install the features, not the bundles, e.g.:
    <feature name="special-server" version="1.0.0" install="auto" resolver="(obr)">
        <feature>camel-blueprint</feature>
        ...
    </feature>
  1. Your declaration of <bundle> dependencies is simply wrong. You specified features, not bundles.
  2. There is no prerequisite attribute for the <bundle> tag and never has been (please adhere to the XSD)
  3. The <repository> can only be declared at the top-level, not inside a feature (also violates the XSD)

Example Features Repository

Based on your example, I've compiled an example features repository including comments in an attempt to clarify the questions a bit more practical:

<?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>
Upwind answered 31/3, 2019 at 11:52 Comment(8)
To be fair, the mixing of terminology is caused by the bizarre formulations and contradictory explanations I have read. There are also many linguistic errors in the documentation e.g. “If you will” instead of “if you would” in your quote above, or even more appropriate would be to avoid the 2nd person altogether by using the passive voice here, “If a .. were used”. Long story short: This makes reading and understanding the documentation a nightmare. In any case, thanks for the time you spent answering my question.Hypoglossal
I totally agree. I've had trouble understanding/interpreting the documentation myself in the past but it has improved a lot since the Karaf 2.x and 3.x days already. I guess the project misses some technical writer at least for cross-reading and to ensure consistent use of terminology and references where appropriate to clarify and reduce the room for potential misinterpretation.Upwind
Any chance you could provide a source/explanation for number 2? For example, how would I know to install the features and not the bundles for Apache Camel and Apache CXF?Hypoglossal
Just added a documented example features.xml based on yours. I hope that clarifies remaining questions. :-)Upwind
I get it. They should have put the autostart functionality of "prerequisite" in something called "autoinstall=true" so that it would be obvious that it can be used with "dependency". Also I noticed that there is no obvious warning if a repository in features.xml does not have a valid URI! I would like to note that I used <bundle>file:deploy/special-server-${project.version}.jar</bundle> to refer to /usr/local/karaf/deploy/special-server-1.0.0.jar.Hypoglossal
Errhh... have you read the README in the deploy/ folder? That directory is meant to be used for automatic deployment of artifacts, not to be included in features. OTOH, with a file: protocol, the feature can only be installed when the Bundle already was put into place by some other external means, which is not explained by the feature declaration. Before going that route, you should really follow best-practices first. You're using Maven anyway, and Karaf is also asking your local Maven repository for bundles, so no need to copy it yourself.Upwind
About the naming of prerequisite, you seem to come from a specific other world. Something like autoinstall would not help anyone as in the end all feature dependencies are going to be started if you install your feature - so auto-install applies to everything. If you think about it, the term prerequisite is quite precise here, as it tells that this dependency needs to be fully working before attempting to install your feature. The term dependency is something I would complain more about here.Upwind
"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." Ignoring the grammatical and spelling errors: Here, "force" could imply Karaf auto installs those features, or that it will fail when those features are not available.Hypoglossal

© 2022 - 2024 — McMap. All rights reserved.