When people first start developing with OSGi, the learning curve can be quite steep. There are several reasons for this:
First of all, designing modular software is hard and becomes even harder when you have to take into account the dynamism that is introduced because every component has its own life cycle. However, the benefits of doing so are huge when it comes to maintaining and evolving software over a longer period of time. Given the fact that by far the biggest cost factor in software development is maintenance, it makes sense to focus on a modular architecture for any software that will be in use for longer periods of time.
Another reason is that historically, tooling support for OSGi has not been great. Yes, there have been plugins for both Maven and Ant, but these were not that well integrated into IDEs and provided a development model that had a compile and deploy cycle that was a lot slower than necessary, given the ability of OSGi to dynamically deploy updates into a running container. Nowadays, Bndtools, a plugin for Eclipse, provides excellent support and a really fast way to develop modular applications, and (experimental) build support using Gradle is making off-line builds lightning fast as well.
However, that’s not what this article is about. I want to focus here on application development and architecture, before discussing tooling solutions.
A popular way of looking at architecture is by using the 4+1 view to describe the system from the viewpoints of the different stakeholders. I’m not going to re-iterate all of these viewpoints and how they’re used. Instead, I would like to zoom in to two of these views and discuss their merit in the context of modular applications in general, and more specifically OSGi.
The Development View
This view looks at the system from a developer’s point of view and since most of the time, a developer works within the IDE, this view should be one that is convenient to work with in that IDE. At first it might seem logical to create a view that contains projects for all the individual bundles. However, many applications consist of hundreds of bundles and having so many projects in an IDE is too much to have an overview. So instead of projects per individual bundle, we’re looking at projects that contain all the code for a certain subsystem of an application. Such subsystems contain multiple bundles, so there are not as many of them. This ensures we keep an overview. It also means we’ve decoupled the development view from the individual bundles, which makes it easier to refactor the way we package our subsystems.
The Physical View
This view looks at the system from a system engineer’s point of view. It is also known as the deployment view. Since the deployable units in OSGi are bundles, this view should describe the individual bundles and how they are grouped and deployed onto physical nodes. Partially this view is also visible within an IDE, as it usually contains some kind of definition for all bundles, and also one or more runnable configurations that describe what bundles go together to create an application. This view however is also one that is used when deploying applications onto nodes using a provisioning server.
The main point I want to drive home here is that there is a fundamental difference between the development and physical view that a lot of tools don’t respect. This is a problem. Both Maven and Eclipse PDE force you to create a project per bundle so eventually you end up with way more projects than can fit on your screen. Changing the way you bundle your application is also made difficult this way and you are less flexible in the sense that you cannot easily create different, overlapping bundles from your code (for example a bundle that contains both API and implementation and a second one that just contains the API). It also means that migrating existing, non-modular applications to OSGi becomes harder as you are suddenly required to change your project setup to create the proper bundles.
Bndtools does this differently. Here you can create as little or many projects as you like and from a project it is easy to create multiple bundles, where each bundle is free to take any subset of packages defined within that project. This gives you a better overview, and it eases migration. If you also use Apache ACE as a provisioning server and link it to Eclipse and a Continuous Build system, you end up with a pretty flexible and powerful way to develop, test and deploy OSGi applications.