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>
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
:
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">
<feature name="special-server" version="1.0.0" install="auto" resolver="(obr)">
<feature>camel-blueprint</feature>
...
</feature>
<bundle>
dependencies is simply wrong. You specified features, not bundles.prerequisite
attribute for the <bundle>
tag and never has been (please adhere to the XSD)<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:="(&(osgi.ee=JavaSE)(version>=1.8))"</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>