Using the OSGi Bundle Repository in OSGi and Apache Felix 3.0


OSGi and Apache Felix 3.0 Beginner's Guide

OSGi and Apache Felix 3.0 Beginner's Guide

Build your very own OSGi applications using the flexible and powerful Felix Framework

  • Build a completely operational real-life application composed of multiple bundles and a web front end using Felix
  • Get yourself acquainted with the OSGi concepts, in an easy-to-follow progressive manner
  • Learn everything needed about the Felix Framework and get familiar with Gogo, its command-line shell to start developing your OSGi applications
  • Simplify your OSGi development experience by learning about Felix iPOJO
  • A relentlessly practical beginner's guide that will walk you through making real-life OSGi applications while showing you the development tools (Maven, Eclipse, and so on) that will make the journey more enjoyable
        Read more about this book      

(For more resources on Apache, see here.)


The OSGi Bundle Repository (OBR) is a draft specification from the OSGi alliance for a service that would allow getting access to a set of remote bundle repositories. Each remote repository, potentially a front for a federation of repositories, provides a list of bundles available for download, along with some additional information related to them.

The access to the OBR repository can be through a defined API to a remote service or as a direct connection to an XML repository file.

The bundles declared in an OBR repository can then be downloaded and installed to an OSGi framework like Felix. We will go through this install process a bit later.

The OSGi specification for OBRs is currently in the draft state, which means that it may change before it is released.

The following diagram shows the elements related to the OBR, in the context of the OSGi framework:

The OBR bundle exposes a service that is registered with the framework. This interface can be used by other components on the framework to inspect repositories, download bundles, and install them.

The Gogo command bundle also registers commands that interact with the OBR service to achieve the same purpose. Later in this article, we will cover those commands. API-based interaction with the service is not covered, as it is beyond the scope of this article.

The OBR service currently implements remote XML repositories only. However, the Repository interface defined by the OBR service can be implemented for other potential types of repositories as well as for a direct API integration.

There are a few OSGi repositories out there, here are some examples:

Those may be of use later, as a source for the dependencies of your project.

The repository XML Descriptor

We already have an OBR repository available to us, our releases repository.

Typically, you'll rarely need to look into the repository XML file. However, it's a good validation step when investigating issues with the deploy/install process.

Let's inspect some of its contents:

<repository lastmodified='20100905070524.031'>

Not included above in the automatically created repository file is the optional repository name attribute.

The repository contains a list of resources that it makes available for download. Here, we're inspecting the entry for the bundle com.packt.felix.bookshelf-inventory-api:

presentationname='Bookshelf Inventory API'
Defines the API for the Bookshelf inventory.</description>
<category id='sample'/>
<capability name='bundle'>
<p n='symbolicname'
<p n='presentationname' v='Bookshelf Inventory API'/>
<p n='version' t='version' v='1.4.0'/>
<p n='manifestversion' v='2'/>
<capability name='package'>
<p n='package'
<p n='version' t='version' v='0.0.0'/>
<require name='package'
extend='false' multiple='false'
Import package com.packtpub.felix.bookshelf.inventory.api

Notice that the bundle location (attribute uri), which points to where the bundle can be downloaded, relative to the base repository location. The presentationname is used when listing the bundles and the uri is used to get the bundle when a request to install it is issued.

Inside the main resource entry tag are further bundle characteristics, a description of its capabilities, its requirements, and so on.

Although the same information is included in the bundle manifest, it is also included in the repository XML for quick access during validation of the environment, before the actual bundle is downloaded.

For example, the package capability elements describe the packages that this bundle exports:

<capability name="package">
<p n="package" v="com.packtpub.felix.bookshelf.inventory.api"/>
<p n="version" t="version" v="0.0.0"/>

The require elements describe the bundle requirements from the target platform:

<require extend="false"
multiple="false" name="package" optional="false">
Import package com.packtpub.felix.bookshelf.inventory.api
<!-- ... –->

The preceding excerpts respectively correspond to the Export-Package and Import-Package manifest headers.

Each bundle may have more than one entry in the repository XML: an entry for every deployed version.

Updating the OBR repository

The Felix Maven Bundle Plugin attaches to the deploy phase to automate the bundle deployment and the update of the repository.xml file.

Using the OBR scope commands

The Gogo Command bundle registers a set of commands for the interaction with the OBR service. Those commands allow registering repositories, listing their bundles, and requesting their download and installation.

Let's look at those commands in detail.

        Read more about this book      

(For more resources on Apache, see here.)


The obr:repos command (repos for short, when there are no name conflicts) allows us to manage the repositories of the OBR service.

Its usage is as follows:

g! help repos

repos - manage repositories
scope: obr
String ( add | list | refresh | remove )
String[] space-delimited list of repository URLs

The repos add operation is used to register repositories with the OBR service. For example, let's register our releases repository:

g! repos add file:///C:/projects/felixbook/releases/repository.xml

Registered repositories are not kept between restarts of the framework. To have repositories automatically registered at startup, set the property obr.repository.url in the framework conf/ file. Its value is a space-separated list of repository URLs.

For example, the default value for this property is the Felix releases repository:


The repos remove operation unregisters a previously added repository.

The repos list operation is used to list the registered repositories, for example:

g! repos list

Here we have the default repository and the one we've just added.

The repos refresh operation will reload the repositories that are passed as a parameter.


The obr:list command finds bundles in the registered repositories and displays them. The search may be constrained by a filter on bundle names.

Its usage is as follows:

g! help list

list - list repository resources
scope: obr
-v, --verbose display all versions
String[] optional strings used for name matching

The -v (or --verbose) flag is used to display more information on each bundle, including all versions and the bundle-symbolic name.

For example, the following lists the bundles in the repository containing the sub-string book and displays verbose information:

g! list -v book
Bookshelf Inventory API
[com.packtpub.felix.bookshelf-inventory-api] (1.4.0)
Bookshelf Inventory Impl - Mock
[com.packtpub.felix.bookshelf-inventory-impl-mock] (1.4.0)

The output was reformatted for clarity.


The obr:info command retrieves and displays the information available in the repository for one or more bundles.

The targeted bundles are passed as a space-separated list, each entry specified by display name, symbolic name, or bundle ID.

The syntax is as follows:

g! help info

info - retrieve resource description from repository
scope: obr
String[] ( <bundle-name>
| <symbolic-name> | <bundle-id> )[@<version>] ...

For example, the following is the repository information of the "Apache Felix Gogo Shell Runtime" (bundle ID 3):

g! obr:info 3
Apache Felix Gogo Shell Runtime
symbolicname: org.apache.felix.gogo.runtime
category: [org.apache.felix.gogo]
description: Apache Felix Gogo Shell
size: 58198
presentationname: Apache Felix Gogo Shell Runtime
id: org.apache.felix.gogo.runtime/0.2.0
version: 0.2.0

{manifestversion=2, symbolicname=org.apache.felix.gogo.runtime,
presentationname=Apache Felix Gogo Shell Runtime, version=0.2.0}
{package=org.osgi.service.command, version=0.2.0}
{package=org.osgi.service.threadio, version=0.2.0}


The obr:deploy command is used to download bundles from the repository and install them onto the Felix instance, with the possibility of optionally starting them.

The command usage is as follows:

g! help deploy

deploy - deploy resource from repository
scope: obr
-s, --start start deployed bundles
String[] ( <bundle-name>
| <symbolic-name> | <bundle-id> )[@<version>] ...

The -s (or --start) flag is used to request the start of the bundles that were just installed.

We will use this command in a short while to install and start our Book Inventory API and implementation bundles.

obr:source and obr:javadoc

The obr:source and obr:javadoc commands are used to download a bundle's sources and JavaDocs archives (if present) to a local directory, and to optionally extract them.

The targeted bundles are specified as a space-separated list of references, each reference being the bundle-symbolic name, presentation name, or ID, with an optional version specification.

The obr:source and obr:javadoc commands have similar usage. The following command is that of the javadoc:

g! help javadoc

javadoc - retrieve resource JavaDoc from repository
scope: obr
-x, --extract extract documentation
File local target directory
String[] ( <bundle-name>
| <symbolic-name> | <bundle-id> )[@<version>] ...

The -x (or --extract) flag is used to request that the archive be extracted once it is downloaded.

There is a name conflict between the obr:source and gogo:source commands. The fully scoped name must be used when calling those commands.

Updating bundles in the repository

As you go through your development cycle, you'll need to refresh the bundles on your framework with their latest versions for testing.

The obr:refresh command reloads the repository listing from its source and updates the list of available bundles. However, this does not mean that the bundles have been refreshed. For this, you'll need to update the bundle.

The full cycle at each rebuild of a bundle (assuming you're using the same version) would be as follows:

  1. Deploy the bundle and update the repository descriptor, using Maven.
  2. Refresh the URL; this is done in the Felix console, using the following obr:refresh command:
    -> repos refresh file:/C:/projects/felixbook/releases/repository.xml


  3. Update the bundle using the felix:update &gtid< command.

This command finds the latest version of the bundle and installs it. If the bundle was previously started, it will be restarted after the installation.

Updating a bundle may not work as well as expected if the installation failed because classes were not found. In those cases, it's better to uninstall and then deploy it again.

You will find yourself going through this cycle often. Alternatively, you can use a direct file install using the felix:install command and then update the bundle using the felix:update command. This is useful for fast deploy-test cycles re-using the same version of the bundle.

Installing the Inventory bundles to Felix

Now that we know more about how to operate the OBR service in Felix, we're going to install them on our OSGi framework.

If you haven't done so already:

  • Start up your Felix framework instance
  • Add the releases repository URL to the OBR service
        Read more about this book      

(For more resources on Apache, see here.)

Time for action – install the inventory bundles

We start by listing the target bundles, to make sure they're there and to have their names, for easy copy-and-paste.

g! list book
Bookshelf Inventory API (1.5.0)
Bookshelf Inventory Impl - Mock (1.5.0)

Since we've declared the bookshelf inventory API as a dependency of the mock implementation, we only need to specifically deploy the implementation.

First, we set the initial bundle level to 2 (Tier 3 services), and move the framework level to that level right away:

g! bundlelevel -i 2
g! frameworklevel 2

Then we use the obr:deploy command to deploy the bookshelf implementation:

g! deploy -s "Bookshelf Inventory Impl - Mock"
Target resource(s):
Bookshelf Inventory Impl - Mock (1.5.0)

Required resource(s):
Bookshelf Inventory API (1.5.0)

Starting Book Inventory Mock Impl

The bundle listing now shows the newly installed bundles:

g! lb
ID|State |Level|Name
0|Active | 0|System Bundle (3.0.1)
1|Active | 1|Apache Felix Bundle Repository (1.6.2)
2|Active | 1|Apache Felix Gogo Command (0.6.0)
3|Active | 1|Apache Felix Gogo Runtime (0.6.0)
4|Active | 1|Apache Felix Gogo Shell (0.6.0)
5|Active | 1|Bookshelf Inventory API (1.5.0)
6|Active | 1|Bookshelf Inventory Impl - Mock (1.5.0)

Bundles 5 and 6 are those we've just installed and started.

What just happened?

Alright, this is cool. Let's go back through it step-by-step.

Someone (in this case, it was us) has deployed a bundle onto their OBR. Now this OBR could be local, as it is here, but could also be hosted online (for example, as is the one for the Felix releases at

We have registered our releases OBR with the Bundle Repository service (while we were looking at the obr:repos add command earlier), which resulted in it now being aware of the "Bookshelf Inventory API" and the "Bookshelf Implementation - Mock" bundles.

Then we requested the Bundle Repository to start the "Bookshelf Inventory Impl - Mock", calling it by name. The Bundle Repository retrieves the information relating to that bundle, namely, the bundle URI, from its cached listing.

However, the inventory mock implementation bundle declares a dependency on the inventory API. The Bundle Repository matches this dependency with the "Bookshelf Inventory API" bundle and installs it.

Then, as all the dependencies required for the "Bookshelf Inventory Impl - Mock" bundle are satisfied, it installs it.

Having specified the -s flag, the installed bundles are started.

When the "Bookshelf Inventory Impl - Mock" bundle is started, its bundle activator's start() method is called. This is when our message "Starting Book Inventory Mock Impl" is printed on the standard output.

Dependency management

The example we've just looked at is a simple one, with a shallow level of dependencies; yet it already shows the value gained from the use of a proper dependency management tool. As bundles become richer in features, their dependency on other bundles, whether internal or third party, grows into a complex tree (sometimes a graph with potential cycles).

Keeping a close check on the dependencies of each project reduces the potential issues relating to the deployment of bundle upgrades. It will save you from lengthy searches for the missing dependencies—usually in the late hours of the night.

It is recommended to keep a checklist of those dependencies, the versions of each that have been tested and approved and the version that's currently being used. Also include their assigned OBR repository URL for quick access when using obr:repos add.

Pop Quiz

  1. What is an OBR?
    1. It's OSGi's way of storing bundles
    2. It's a service for querying repositories hosting OSGi bundles
    3. It's a service that manages installed bundles
  2. What's the main difference between the felix:install and obr:deploy commands?
    1. There's no difference
    2. The main difference is that obr:deploy finds and installs dependencies
    3. The main difference is that obr:deploy uses the bundle presentation name
  3. How do you install and start a bundle using OBR?
    1. I use obr:deploy; it will automatically start the bundle when it's installed
    2. I use obr:deploy to install the bundle, then felix:start to start it
    3. I use obr:deploy with the -s flag to install and then start the bundle
  4. How do you update an OBR repository?
    1. I submit a request to the OSGi alliance; they will update it
    2. I copy the bundle and then manually update the repository XML file
    3. I use the bundle plugin in Maven to update the repository on bundle deploy


In this article, you have learned about OSGi Bundle Repository. You've also looked at:

  • The OBR service and the repository XML descriptor
  • How to manage the registered OBR repositories using the obr scope commands
  • How to find and deploy a bundle from an OBR repository to Felix and update it when it is modified

Further resources on this subject:

You've been reading an excerpt of:

OSGi and Apache Felix 3.0 Beginner's Guide

Explore Title