Getting Started with Bookshelf Project in Apache Felix


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.)

A simple Bookshelf project

The case study we will construct here is a three-tiered web-based bookshelf application. Each tier consists of a functional area of the application.

The first tier is the data inventory tier, which is responsible for storing the books as well as providing management functionality.

The second tier, the main bookshelf service, holds the business logic around the bookshelf functionality.

The third tier is the user interaction tier. It provides user access to the application through a command-line interface at first, then through a simple servlet, and later through a JSP web application.

This split between the user interface, business logic, and inventory is good practice. It adds flexibility to the design by allowing the upgrade or replacement of each of the layer implementations without impacting the others and thus reducing regression testing.

Let's look at each of those layers in more detail.

The data inventory tier

For our case study, we will need a data inventory layer for storing, searching, and retrieving books.

The Book interface defines the read-only book bean and it provides the user access to the bean attributes. This interface is used when the Book entry does not require any updates. The MutableBook interface exposes the attribute-setting methods for the book bean. It is used when the caller needs to update the bean attributes.

This separation between Book and MutableBook is especially useful when developing a multi-threaded, multi-session implementation of the data inventory repository. It allows us to keep track of changes by monitoring the beans as they change and notify components of those changes when needed.

We will define a BookInventory interface that abstracts over the repository implementation specifics.

In addition to the CRUD functionality, the book inventory interface also offers a factory method for creating new book entries. This factory method gives the caller a mutable book.

What's CRUD?

CRUD is short for Create-Retrieve-Update-Delete. It is the typical functionality-set expected from an inventory service:

  • Create: Add a new book to the inventory. This operation typically checks the repository for an item with the same identifier (unique reference) and throws an exception if there's an attempt to add an item that already exists.
  • Retrieve: Load a book based on its unique reference, also get a list of references of items that match a set of filter criteria
  • Update: Modify an existing book properties, based on its unique reference
  • Delete: Remove an existing book from the inventory based on its unique reference

We'll separate the inventory API definition from its implementation, packaging each of them in its own bundle. It is recommended that you write another implementation for those interfaces—one that's based on permanent storage, when you're more comfortable with the process.

The separation between the API and implementation will allow you to swap an implementation with another one when it is ready. We will focus on the mock implementation(out of the scope of this article) and leave it to you to implement other potential flavors of it (in the previous dashed boxes).

        Read more about this book      

(For more resources on Apache, see here.)

The business logic tier

The middle tier, or the business logic tier, of this application is the bookshelf service API and implementation. The bookshelf service implementation uses the inventory functionality exposed by the data tier, delegating book storage functionality. It also overlays application business logic by enriching the operation operation-set.

For example, one of the business logic functionalities, integrated into the bookshelf service, is user authentication. This is defined as an interface that the BookshelfService extends.

Some classes have been hidden for clarity in the preceding diagram.

For the sake of making the point on API-implementation loose coupling, our case study will not separate the bookshelf service API from its implementation. This will allow you to compare the impact of changes to the bookshelf service implementation to those made to the inventory implementation.

The user interaction tier

The upper-most layer in our application is the user interaction or presentation layer. The presentation layer integrates with the business logic layer and exposes a few flavors of interfaces accessible to the application user.

The user interaction layer in our case study will be composed of two flavors of interfaces:

  • Console text user interface: Providing users access to the bookshelf application functionality through the Felix command-line shell
  • Web-based graphical interfaces: Providing users access to the application functionality through a web browser

The console text user interface is simpler to implement and gives early access to the application operations. The web-based graphical interface is covered later on.

The following shows the bundles that will be implemented as part of the user interaction tier and their relationship with the business logic tier.

The bookshelf-service-tui bundle will implement text user interface commands for two of the operations defined for the bookshelf service, namely, the book:search and book:add commands. The remaining commands will be left for you to implement.

The bookshelf-servlet bundle will provide a servlet graphical interface to the bookshelf service. The servlet is encoded to generate HTML and respond to user requests to the following operations:

  • Listing bookshelf groups
  • Listing books in a group
  • Searching books by author
  • Adding a book

The bookshelf-webapp bundle will provide the same functionality as the servlet bundle, implemented using Java Server Pages (JSP).

OSGi, Felix, and...

It is important to keep a clear separation between materials that are OSGi-specific and those that are Felix-specific. Recognizing and following the OSGi-specific directives allows you to develop bundles for any framework that is OSGi-compliant.

The OSGi core specifications which govern the way an OSGi framework must behave and the rules required to be followed by the bundles targeted for an OSGi framework.

Felix is an OSGi-compliant service platform implementation. It also provides a selection of bundles that are OSGi-compliant. The sections having to do with installing and operating Felix are Felix-specific.

The Log Service and Http Service implementations cover bits from OSGi specification as well as ones specific to the Felix implementation. Understanding which sides are part of the OSGi specification and which parts are Felix-specific will help when you want to replace the implementation bundle from one provider to another.

Furthermore, additional hints and discussions around general design-related topics and tools that help with the development activities apply to a context wider than that on which this book focuses. They aim to augment the basic integration requirements with ones that may improve the development experience.

Taking it step-by-step

We will construct this target application in small steps from the bottom up. At every step, the functionality related to OSGi and to Felix will be introduced and explained, thus constructing your knowledge base progressively.

Here, we've established the scope of work and defined the application blueprint. The rest of the book will take you through the implementation and testing of the application.

For the first integration with the OSGi framework, to understand how a bundle interacts with it using bundle activators and the bundle context, we start with the inventory bundles(out of the scope of this article). Those require no interaction with other bundles and will be a good start.

The Maven build mechanism is used to simplify the development of OSGi bundles. It will take you through the definition of a POM for the bundle, the structure of the project contents, and the execution of the build lifecycle to deploy it.

After learning about the OBR service, using the OSGi Bundle Repository, you'll install and start the inventory bundles on the Felix framework and quickly test them.

By then, you would have covered a complete develop-to-test cycle; it's the long "Hello world" that covers all that you need for a fully validated environment.

As you have no interface to interact with the bundle service yet, the testing is done as part of the bundle startup in the bundle activator code. This is later removed when shell commands are implemented for the application.

The next step is to learn how to interact with other bundles in the framework.

Dependency injection is introduced with iPOJO. This adds a layer of separation between our bundles and the framework.

The graphical interface world deals with building a simple servlet, while introducing the OSGi Http Service and its Felix implementation.

OSGi Web Containers, which allow the deployment of Web Application Bundles (WABs) and Web Archives (WARs) and look at the Pax Web services to provide this functionality.

Felix Web Management Console provides a graphical management interface to the Felix framework and some of its common services.

Pitfalls and Troubleshooting looks into some of the common pitfalls while developing bundles and ways to troubleshoot and resolve them.

        Read more about this book      

(For more resources on Apache, see here.)

Some conventions

During this case study, we'll create a good deal of bundles for deployment. Here we will define the common conventions that will be used for identifying the bundles and organization of the Java code.

A bundle is identified by a symbolic name, associated with a version sequence. It is also, usually, given a name. I have chosen a common group identifier for all the bundles com.packtpub.felix and a common bundle artifact base prefix com.packtpub.felix.bookshelf-. The common group identifier will also be used as the base package for the Java code.

The Book Inventory API bundle would be given the symbolic name com.packtpub.felix.bookshelf-inventory-api and its Java classes would be organized under the package com.packt.felix.bookshelf.inventory.api. Notice the switch from dot to dash separation; this allows a quick visual split between the group and artifact IDs of the project. In this case, com.packt.felix is the group ID and bookshelf-inventory-api is the artifact ID.

In regular development contexts, an artifact's version progresses following best practices, rules that were put in place to transmit information about compatibility between different versions of a bundle.

This compatibility information is encoded in three parts of a version string: the major, minor, and patch level. Typically, a bundle would start with a major version of 0 until it is first released. While its major version is 0, the interfaces exposed by the bundle are still in development mode and may undergo any change found to improve them.

When the bundle is released, it is given the version 1.0.0. After this point, changes to the bundle that do not affect the exposed interfaces impact the patch level of the version. For example, a bundle with version 1.0.0 undergoes bug fixes that do not affect its interfaces. This bundle is released with version 1.0.1.

Backward compatible changes to a bundle's interfaces impact the minor version part and reset the patch level. For example, if a new getter method is added to an interface in a bundle with version 1.2.1, it would be released with version 1.3.0. In this instance, a component that had a dependency on this bundle when it had version 1.2.1 can use the one with version 1.3.0 without requiring any changes to its code.

A change in the major version of a bundle means that the changes to the functionality are not backwards compatible. This may include removal of methods, changes in the return types, or an optional bean property that becomes mandatory.

The following are the bundles we will produce as part of our case study:

  • com.packt.felix.bookshelf-inventory-api: The Book Inventory API bundle, released in Chapter 5 with version 1.5.0
  • com.packt.felix.bookshelf-inventory-impl-mock: The Book Inventory Mock Implementation bundle.
  • com.packt.felix.bookshelf-service: The Bookshelf Service bundle.
  • com.packt.felix.bookshelf-service-tui: The Bookshelf Service Text-UI commands bundle.
  • com.packt.felix.bookshelf-servlet: The Booshelf Servlet bundle.
  • com.packt.felix.bookshelf-webapp: The Bookshelf Web application bundle.


One of the most important parts in the preparation of a project is the definition of the overall design and the setting of a specific scope. In this article, we have prepared the grounds for our bookshelf case study. We have looked at the tiered layout of the application and the mapping of the different components of the bookshelf case study to the data, business logic, and presentation tiers.

We have:

  • Designed the bookshelf case study, describing its components and their mapping to the data inventory, business logic, and presentation tiers
  • Set a specific scope for the work to be covered in this book as part of the case study
  • Laid down a few naming conventions for the bundles that will be produced

Now, it's time to start with the data inventory bundles.

Further resources on this subject:

You've been reading an excerpt of:

OSGi and Apache Felix 3.0 Beginner's Guide

Explore Title