Knapsack for Apache Felix

Knapsack is a launcher for the Apache Felix OSGi Framework for Linux-like systems.

Knapsack was born out the desire to remove some of the end-user complexities with more full-featured launchers, and is designed for interactive use. The problem that knapsack addresses is; get an OSGi framework up and running with a minimum of fiddling.

Design Motivations

Knapsack is both a little less and a little more than Felix's built-in launcher. It's less in that it does not use runlevels and all bundle install/start configuration is done via the filesystem, and it does not allow for specifying bundle start configuration via property files. It is a little more because a few bundles are started by default, and knapsack includes a built-in shell mechanism (see below) so it is functionally complete for interactive work. Knapsack's design is a result of the following opinions:

OSGi Shells are overkill for basic administrative tasks.

Most of the time, we ask "Is my bundle running?" or "is the HTTP service available?". OSGi shells are a way of answering that question, but are worlds into themselves and the source of unnecessary complexity. Based on work from the OSGiFS prototype, Knapsack uses netcat, a simple shell script, and a socket to expose OSGi shell functions to the native shell. For example, to see running bundles

$ bin/bundles 
ACTIV 	[ 0]org.apache.felix.framework (0.0.0) 	Bundle
INSTL 	[ 1]b1 (1.0.0.201107041019) 	/tmp/eclipse-knapsack/bundle/b1_1.0.0.201107041019.jar
Is all that's required. Grep, pipe, and xargs your heart out. All OSGi state information is exposed via the native shell in a similar manner. To get all available commands, run:
bin/help
Like other shell systems, Knapsack uses the service registry so new commands can be added dynamically by other bundles.

Native file metadata and operations are sufficient for bundle management.

Typically OSGi launchers will have a set of properties that can be used to configure where bundles start from, in which order, if they should be installed or started, and at what run-level. This ends up to be a headache to configure and change when you end up setting up a framework by hand. Knapsack's solution is to:

  1. In properties, specify the set of "bundle" directories.
  2. Scan the directories in alpha order, installing them into the framework.
  3. If the execution bit is set on the file, start the bundle.
In this manner, start levels can be simulated based on alpha order (like the Linux init system), but more importantly, the bundle storage mechanism is just the filesystem, so no need to read and edit complex lists of properties. Essentially the workflow to start a new bundle is to copy it into a directory and run:
$ bin/update 
Rescanning and updating bundles from configured directories.

The storage dir is a source of pain when debugging bundles.

By default Knapsack will not keep bundles from pre-existing runtime sessions. Non-executable state is stored in /configadmin so that it doesn't get clobbered every time the framework restarts. As a result, there is one place that bundle code comes from, /bundle. (This is configurable)

Setup of an OSGi-based application is too hard.

Most often, we rely on tooling to create and configure a framework instance, but what if you want more control or don't want to use Eclipse?

From a terminal, running a program goes something like $ myprogram <enter>. Knapsack strives for this level of simplicity by creating default configuration, and exposing the OSGi environment to the user via the system shell. On start, knapsack will create it's configuration if it does not already exist, and by relying on filesystem the configuration remains simple.
Additionally, it is easy to setup modular defaults for system properties and ConfigAdmin Managed Services. Modular in the sense that properties for a given bundle can be isolated from other properties, rather than having one global configuration file. Knapsack will scan files in /defaults and load them as either system properties (if the file has a '.properties') file extension, or as a managed service (filename being the PID). It will not overwrite existing ConfigAdmin configurations. This is useful for build-time to have modular configuration that is loaded only once.

Some things are better have around from the get-go.

When you run knapsack the first thing you see is:

INFO: Framework started in 2.39 seconds with activators: [org.apache.felix.log.Activator@1112783, org.apache.felix.cm.impl.Configura
tionManager@1394894, org.knapsack.Activator@1cbfe9d]
This is showing that the Apache Log and ConfigAdmin services, along with Knapsack, are starting with the framework. Why is this good? OSGi, as a module system, is designed for extreme flexibility. Almost all services are optional. However when focusing on application development is a lot easier if you have a few services around. LogService, LogReader, and ConfigAdmin are immediately available. These services start with the framework, so from a bundle's perspective they will always exist. In this regard, Knapsack is similar to Apache Karaf, in that it adds a set of bundles to provide an application platform. However Karaf has more of an enterprise-oriented platform design, and as a result has more features and a larger footprint.

Well-known filesystem operations are best for configuration storage and state modification.

By overloading the concept of an executable file, bundles become executables or libraries. Output is grep-friendly and accessing OSGi runtime state info from scripts is straight-forward. The framework admin does not need to learn a new tool.

Getting Started

Refer to the README for details on how to get started with knapsack.

Source

The source is hosted at github: https://github.com/kgilmer/knapsack

A public Jenkins instance provided by Cloudbees provides a binary.

License

Knapsack is Apache 2.0 licensed.

Project Status

Knapsack has been in active development for the past few months and is intended to have a first production release in July 2011.