Book Image

Apache Karaf Cookbook

By : Jamie Goodyear, Johan Edstorm, Achim Nierbeck, Heath J Kesler
Book Image

Apache Karaf Cookbook

By: Jamie Goodyear, Johan Edstorm, Achim Nierbeck, Heath J Kesler

Overview of this book

Table of Contents (17 chapters)
Apache Karaf Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

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…

  1. 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 a build section.

  2. The next step is editing the POM file's build directives. We add a resources directive to our POM file's build section and maven-resources-plugin and build-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 our features.xml file as described in the preceding code.

  3. The third step is creating a features.xml resource. In the src/main/resources folder, add a file named features.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, and recipe4-all-modules. The recipe4-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.

  4. 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 local m2 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 install moduleA and moduleB, 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.