Appendix C. Generating a Custom Assembly or an Offline Repository

Overview

The Karaf container in JBoss Fuse comes with a large collection of features installed by default. While this offers the advantage of a highly functional container, it requires a large amount of memory and resources. For some deployment scenarios, it can be an advantage to strip down the Karaf container to use the minimal set of features required for your application. A custom assembly is the most effective way to create a stripped down Karaf container that deploys only the features needed for your application.
The same procedure that is used to generate a custom assembly also generates an offline repository.

Custom assembly

A custom assembly is a custom distribution of the Karaf container based on JBoss Fuse, which is generated using a specific toolchain of Maven plug-ins. The quickstart examples include a template, quickstart/custom, which demonstrates how this toolchain works and provides you with the starting point for creating your own custom assemblies.
Note
A custom assembly is generated using essentially the same toolchain as the official JBoss Fuse Karaf container distribution.

Patched custom assembly

If your starting point is a JBoss Fuse rollup patch (which is, in fact, equivalent to a complete distribution of the JBoss Fuse product with patches already applied), and you then follow the steps for generating a custom assembly, what you end up with is a patched custom assembly. No actual patching step needs to be performed in this case, however, because the patch is already built-in to the custom assembly.

Offline repository

An offline repository is a Maven repository that contains a custom collection of Maven artifacts that would otherwise need to be downloaded from the Internet. For JBoss Fuse deployments that lack Internet access, the offline repository makes it possible to run the container in an isolated network by providing all of the Maven artifacts that your application might need. For details about how to install an offline repository in a standalone Karaf container, see chapter "Locating Artifacts with Maven and HTTP" in "Deploying into Apache Karaf".

quickstart/custom example

The quickstart/custom example provides a template for generating your own custom assembly. The default configuration of the custom example includes a very minimal collection of Karaf features. You can easily customize this configuration to specify example which Karaf features you would like to include in the custom assembly.

Procedure to generate a custom assembly or an offline repository

To generate a custom assembly, or a patched custom assembly, or an offline Maven repository, perform the following steps:
  1. Choose the appropriate starting point for this procedure:
    • To generate a custom assembly—download and install the standard install from the Red Hat Customer Portal, as described in Chapter 3, Installing; or
    • To generate a patched custom assembly—download the latest rollup patch from the Red Hat Customer Portal.
  2. Go to the InstallDir/quickstarts/custom project.
  3. Customize the features that will be included in the custom assembly's system/ directory (or in the generated offline repository) by editing the project's pom.xml file. The patch feature and the fabric feature are both required, and must be added to the configuration.
    Open the quickstarts/custom/pom.xml file in a text editor, search for the features-maven-plugin plug-in configuration, and add the patch feature and the fabric feature as children of the configuration/features XML element—for example:
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        ...
        <build>
            <plugins>
                ...
                <!--
                    Step 3: gather all the bundles for the features your want to install
                -->
                <plugin>
                    <groupId>org.apache.karaf.tooling</groupId>
                    <artifactId>features-maven-plugin</artifactId>
                    <version>2.4.1</version>
                    <executions>
                        <execution>
                            <id>add-features</id>
                            <goals>
                                <goal>add-features-to-repo</goal>
                            </goals>
                            <phase>generate-resources</phase>
                            <configuration>
                                ...
                                <features>
                                    <!-- TODO: add the feature you want to use in your custom assembly to the list below -->
                                    <feature>shell</feature>
                                    <feature>admin</feature>
                                    <feature>management</feature>
                                    <feature>camel-blueprint</feature>
                                    <feature>camel-jaxb</feature>
                                    <feature>patch</feature>
                                    <feature>fabric</feature>
                                </features>
                                <repository>target/repository</repository>
                            </configuration>
                        </execution>
                    </executions>
                    ...
                </plugin>
                ...
            </plugins>
        </build>
        ...
    </project>
  4. (Not required for an offline repository) Customize the list of features that will be installed automatically when the custom assembly's container first starts. The patch feature and the fabric feature are both required, and must be added to this list.
    Open the src/main/filtered-resources/etc/org.apache.karaf.features.cfg file and modify the featuresBoot property setting as required, adding at least the fabric feature and the patch feature to the list:
    ...
    # TODO: list the boot features for your own assembly below
    featuresBoot=shell,admin,management,fabric,patch,camel-blueprint,camel-jaxb
  5. Install the JBoss Fuse distribution into your local Maven repository. In the following example, you would replace xxx with the version number in your artifact:
    mvn install:install-file \
         -Dfile=/path/to/fuse/jboss-fuse-karaf-6.3.0.redhat-xxx.zip \
         -DgroupId=org.jboss.fuse \
         -DartifactId=jboss-fuse-karaf \
         -Dversion=6.3.0.redhat-xxx \
         -Dpackaging=zip \
         -DgeneratePom=false
  6. After customizing the configuration of the quickstarts/custom project, build the project as follows:
    mvn clean package
  7. The offline repository is now available in the following directory:
    InstallDir/quickstarts/custom/target/repository
    If the purpose of this build is to create an offline repository, the procedure is now finished and you can skip the remaining steps.
  8. The result of building this project is a custom assembly file, in the following location:
    InstallDir/quickstarts/custom/target/custom-distro-ProductVersion-bin.zip
  9. The custom assembly requires some additional modifications. In preparation for this, unpack the custom assembly file, custom-distro-ProductVersion-bin.zip, into a convenient working location on the file system:
    Working/custom-distro-ProductVersion-bin
  10. To reduce the size of the custom assembly, delete the extras/ subdirectory from custom-distro-ProductVersion-bin (saving about 67 MB).
  11. Create a new baseline archive for the custom assembly, as follows:
    1. Make a copy of the entire Working/custom-distro-ProductVersion-bin directory, to give a copy like the following:
      Working/custom-distro-ProductVersion-bin(copy)
    2. Rename the copied directory, custom-distro-ProductVersion-bin(copy), to the following:
      jboss-fuse-karaf-ProductVersion-baseline
      For example, if the ProductVersion is 6.3.0.redhat-187, the new directory name must be jboss-fuse-karaf-6.3.0.redhat-187-baseline.
    3. Delete the system/ subdirectory from the jboss-fuse-karaf-ProductVersion-baseline directory. In addition, if any of the following subdirectories are present, they can also be deleted (as they are not needed in the baseline):
      data/
      deploy/
      extras/
      quickstarts/
    4. Using an archive tool, compress the jboss-fuse-karaf-ProductVersion-baseline directory in Zip format to give the following archive file:
      jboss-fuse-karaf-ProductVersion-baseline.zip
      The preceding file is the baseline archive for the custom assembly.
  12. Copy the baseline archive to the following subdirectory (must be created) of the original custom assembly, Working/custom-distro-ProductVersion-bin:
    system/org/jboss/fuse/jboss-fuse-karaf/ProductVersion
  13. The custom assembly, Working/custom-distro-ProductVersion-bin, is now complete. If you like, you can compress this directory into a Zip archive and distribute it as is.
  14. Test the new custom assembly to make sure it is working properly. Launch the Karaf container, as follows:
    cd Working/custom-distro-ProductVersion-bin/bin
    ./fuse
    The container should start up without error. To make sure that no errors have occurred, check the log:
    JBossFuse:karaf@root> log:display
    You can also check to see whether all of the expected Karaf features are installed:
    JBossFuse:karaf@root> features:list -i
    When you are finished testing the custom assembly container, shut it down by entering the shutdown console command, and tidy up the custom assembly installation by removing the data/ subdirectory (which holds the data from the current container instance).

Troubleshooting

There are a few common errors you might encounter when attempting to start the custom assembly container. Here is a brief explanation of what these errors mean:
  • The following error indicates that the baseline archive was not correctly installed in the system directory:
    ERROR: Bundle org.apache.felix.framework [0] EventDispatcher: Error during dispatch. (io.fabric8.patch.management.PatchException: Can't find baseline distribution in patches dir or inside system repository.)
    io.fabric8.patch.management.PatchException: Can't find baseline distribution in patches dir or inside system repository.
            at io.fabric8.patch.management.impl.GitPatchManagementServiceImpl.trackBaselineRepository(GitPatchManagementServiceImpl.java:1820)
            at
    ...
  • The following error indicates that the patch feature is not deployed in the container:
    Bundle listed in startup.properties configuration not found: io/fabric8/patch/patch-management/1.2.0.redhat-621092/patch-management-1.2.0.redhat-621092.jar
    Could not create framework: java.lang.Exception: Aborting due to missing startup bundles
    java.lang.Exception: Aborting due to missing startup bundles
    	at org.apache.karaf.main.Main.processConfigurationProperties(Main.java:1281)
    	at org.apache.karaf.main.Main.loadStartupProperties(Main.java:1082)
    	at org.apache.karaf.main.Main.launch(Main.java:346)
    	at org.apache.karaf.main.Main.main(Main.java:561)
  • The following error indicates that the patch feature was successfully deployed, but the required fabric feature is missing:
    ERROR: Bundle io.fabric8.patch.patch-core [49] Error starting mvn:io.fabric8.patch/patch-core/1.2.0.redhat-621092
    (org.osgi.framework.BundleException: Unresolved constraint in bundle io.fabric8.patch.patch-core [49]:
    Unable to resolve 49.0: missing requirement [49.0] osgi.wiring.package; (&(osgi.wiring.package=io.fabric8.api)(version>=1.2.0)(!(version>=2.0.0))))