Deploying applications as a feature
Managing the assembly and deployment of repository locations, bundles, configuration, and other artifacts quickly becomes a major headache for system builders. To combat this, the Karaf community has developed the concept of features. The following figure describes the concept of features:
A feature descriptor is an XML-based file that describes a collection of artifacts to be installed together into the Karaf container. In this recipe, we'll learn how to make a feature, add it to Karaf, and then use it to install bundles.
Getting ready
The ingredients of this recipe include the Apache Karaf distribution kit, access to JDK, Maven, and a source code editor. The sample code for this recipe is available at https://github.com/jgoodyear/ApacheKarafCookbook/tree/master/chapter1/chapter1-recipe4.
How to do it…
- The first step is generating a Maven-based project. For this recipe, we need to create a Maven POM file, set its packaging to
bundle
, and include abuild
section. - The next step is editing the POM file's
build
directives. We add aresources
directive to our POM file'sbuild
section andmaven-resources-plugin
andbuild-helper-maven-plugin
to its plugin list. Consider the following code:<resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources>
In the preceding code, the
resources
directive indicates the location of the features file we'll create for processing. Now, consider the following code:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>filter</id> <phase>generate-resources</phase> <goals> <goal>resources</goal> </goals> </execution> </executions> </plugin>
In the preceding code,
maven-resources-plugin
is configured to process our resources. Now, consider the following code:<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <executions> <execution> <id>attach-artifacts</id> <phase>package</phase> <goals> <goal>attach-artifact</goal> </goals> <configuration> <artifacts> <artifact> <file>${project.build.directory}/classes/${features.file}</file> <type>xml</type> <classifier>features</classifier> </artifact> </artifacts> </configuration> </execution> </executions> </plugin>
Finally,
build-helper-maven-plugin
completes the build of ourfeatures.xml
file as described in the preceding code. - The third step is creating a
features.xml
resource. In thesrc/main/resources
folder, add a file namedfeatures.xml
with the details of your bundles, as shown in the following code:<?xml version="1.0" encoding="UTF-8"?> <features> <feature name='moduleA' version='${project.version}'> <bundle> mvn:com.packt/moduleA/${project.version} </bundle> </feature> <feature name='moduleB' version='${project.version}'> <bundle> mvn:com.packt/moduleB/${project.version} </bundle> </feature> <feature name='recipe4-all-modules' version='${project.version}'> <feature version='${project.version}'>moduleA</feature> <feature version='${project.version}'>moduleB</feature> </feature> </features>
We provide each feature with a name that Karaf will use as a reference to install each element specified in the named feature's configuration. Features may reference other features, thus providing fine-grained control over installation. In the preceding features file, we can see three named features:
moduleA
,moduleB
, andrecipe4-all-modules
. Therecipe4-all-modules
feature includes the content of the other two features.Tip
If you need to include a JAR file that is not offered as a bundle, try using the
wrap
protocol to automatically provide the file with the OSGi manifest headers. For more information, see https://ops4j1.jira.com/wiki/display/paxurl/Wrap+Protocol. - The final step is building and deploying our feature. Using our sample recipe project, we will build our feature by executing
mvn install
. This performs all of the feature file variable substitutions and installs a processed copy in your localm2
repository.To make our feature available to Karaf, we'll add the feature file's Maven coordinates as follows:
karaf@root()>feature:repo-add mvn:com.packt/features-file/1.0.0- SNAPSHOT/xml/features
Now, we can use Karaf's
feature
commands to installmoduleA
andmoduleB
, as shown in the following command-line snippet:karaf@root()>feature:install recipe4-all-modules Apache Karaf starting moduleA bundle Apache Karaf starting moduleB bundle karaf@root()>
Using
feature:install
in this fashion helps to promote repeatable deployments and avoid missing component installations that are not caught by the OSGi environment (if no bundle dependencies are missing, then as far as the container is concerned, all is well). We can verify whether our feature is installed by invoking the following command:karaf@root()>feature:list | grep –i "recipe"
We can then observe whether our feature is listed or not.
How it works…
When Karaf processes a feature descriptor as a bundle, hot deployment, or via a system start-up property, the same processing and assembly functions occur, as shown in the following figure:
The feature descriptor invocation is transformed into a list of artifacts to be installed in the OSGi container. At the lowest level, individual elements in a feature have a handler to obtain the described artifact (such as a bundle, JAR file, or configuration file). Our sample feature uses Maven coordinates to obtain bundles, and the Maven handler will be called to process these resources. If an HTTP URL was specified, then the HTTP handler is called. Each artifact in the specified feature will be installed until the entire list is processed.
There's more…
The How to do it… section of this recipe outlines a general methodology to produce a feature file for your projects and automate the filtering of resource versions. From Apache Karaf's point of view, it just processes a well-formatted features file so that you can handwrite the file and deploy it directly into Karaf.
Feature files have additional attributes that can be used to set bundle start levels, flag bundles as being dependencies, and set configuration properties. For more information, visit http://karaf.apache.org/manual/latest/users-guide/provisioning.html.
An advanced use case of Karaf feature files is to build a KAraf aRchive (KAR). A KAR file is the processed form of a feature file, collecting all the required artifacts into a single deployable form. This archive is ideal for deployment when your Karaf instance will not have access to remote repositories, as all required resources are packaged in the KAR file.
See also
- We'll be using the features concept of Apache Karaf in several chapters of this book to simplify the installation of Apache Camel, ActiveMQ, and CXF among other projects.