"it is generally impractical to treat a bundle as the basic unit of deployment."
This statement is a bit too strong I think, given that the bundle would be considered the basic deployable unit by users already familiar with OSGi. It might be better to re-phrase as something like:
"it is often convenient to aggregate inter-dependent or related bundles into a larger unit of deployment."
"Essentially, a feature is created by adding a new feature element to a special
kind of XML file, known as a feature repository."
Often referred to synonymously as as a "features URL". Neither terminology is really satisfactory, especially the former as it connotes a centralized location where all the bundles are stored (like a maven repository or the OBR) which of course it isn't. So it might make sense to emphasize the point that a features repository is really just an aggregation of references to inter-dependent or related bundles, not a location where the bundles themselves are stored.
"Create a local feature repository"
The reference to locality may be confusing as the standard features repos shipping with the ESB would also be available locally (under the <smx_install_dir>/system dir) as well as being remotely accessible via the fusesource maven repo. You might want to call it a custom features repository instead.
The top-level features element may optionally be decorated with a name attribute. See for example
If the name isn't specified, Karaf will default to a generic name like "repo-0".
"Add the local repository URL to the features service"
Cart before the horse somewhat? Surely some feature elements should be defined in the new features repo before running features:addUrl?
"In order to make the new feature repository available to the Apache Felix kernel ..."
Repeated used of 'kernel' in this sentence may confuse, given that we switched over from the old ServiceMix Kernel to Apache Felix Karaf for this release. May be better as:
"In order to make the new feature repository available to the Karaf features service ..."
Replace all "psc-01-00RC1" with "fuse-01-00".
"You can optionally specify a version attribute on the feature element, if you want to keep track of the
feature's version number."
It would be more a case of assigning a non-zero version to the feature, as opposed to just keeping track of the version. When versions are used, a specific version of a particular feature can be specified, e.g.
features:install cxf-jaxrs 4.2.0-fuse-01-00
"To check whether the kernel successfully parses the new feature entry"
Similar comment to the above, probably best to refer to it as the features service.
"but you should be able to find the entry for your new feature (in this
case, example-camel-bundle) by scrolling back through the listing."
or by simply shortening the list to only those features are actually installed via the -i,--installed option:
karaf@root> features:list -i
or by grep'ing for the particulat feature
karaf@root> features:list | grep example-camel-bundle
"The features:refreshUrl command forces the kernel to reread all the feature repositories"
Unless you specify a URL argument, in which case only that repo is refreshed.
"Each child feature element contains the name of a feature on which the
current feature depends."
A version can be specified as well, e.g.
<feature name='camel-core' version='2.2.0-fuse-01-00'>
This encodes a dependency of the camel-core feature (v. 2.2.0-fuse-01-00) on the spring feature (v. 2.5.6.SEC01).
"When you deploy a feature with dependent features,
the dependency mechanism checks whether or not the dependent features
are available in the container. If not, the dependency mechanism automatically
loads the missing dependencies (and any recursive dependencies)."
Maybe better to use "installed" and "installs" as opposed to "available" and "loads".
"For example, for the custom FUSE Mediation Router feature,
example-camel-bundle, you can specify explicitly which standard Apache
Camel features it depends on."
This could confuse in the sense of implying the Apache version of the camel features were being depended on, as opposed to the FUSE versions, especially since the next example refers to unversioned camel-core etc features.
These two features have been superceeded by the single camel-spring-osgi feature.
"Where the name attribute of the config element specifies the scope of the
In config admin service terminology, this is the persistent ID or PID, as opposed to the scope.
You also should specify that this config value may over-ridden via a properties file called:
which could be created via your favourite text editor or via the karaf shell commands:
karaf@root> config:edit org.fusesource.fuseesb.example
karaf@root> config:propset prefix MyOtherTransform
"consider the following Spring XML file that accesses the OSGi
configuration properties using Spring DM"
Would it be worth also giving a blueprint example of property placeholder substitution?
Should read: etc/org.apache.felix.karaf.features.cfg
"You can modify the configuration to customize the features that are installed
as FUSE ESB kernel starts up."
Note the featuresBoot etc. only have an impact the first time the features service is booted. So in order to pick up any changes, you would need to clear the slate by deleting the data/cache directory.
Missing some text here?
Would it be worth also noting that Karaf exposes a FeaturesService MBean? This provides attributes that allow the features & repos to be browsed and also operations allowing the repos & features to installed/uninstalled.
This example seems to exploit a non-standard feature of Apache Geronimo. Is this the recommended approach?
That JAAS example is showing something a little different, specifically substituting in system properties as opposed to config admin service properties. The former is very useful too, and in fact we use the Geronimo custom namespace internally in the blueprint configs for the Karaf and SMX bundles for this purpose. However it would not be a direct analogue for the Spring-DM example in the docco, which is based on the config admin service.
To illustrate the difference, here's a kinda cool example that uses both approaches. The defaults for the config admin service properties may in this case be over-ridden by system properties, so both property placeholders are in play. So for example, if destinationName property isn't set in etc/org.apache.servicemix.jbi.cluster.config.cfg, then its value may be over-ridden via JAVA_OPTS="-Dservicemix.cluster.destination=myClusterQueue".
That is indeed a very nifty example, but I think I should probably discuss it in chapter 8 (Deploying an OSGi Service), which is where I discuss Blueprint configuration in more detail.