In this post we’ll talk about what we can achieve building a software solution based on OSGi technology. I’d say the base things are: modularity & class loading mechanism, bundles lifecycle management, service discovery. By the way, guys, before we start: everything described here relates to a Java programming language only.
Everyone understands that code structured into layers and modules with strict interfaces between them is a “must have” for a successful enterprise software project. In Java to achieve modularity we use packages and imports – I call this conventional modularity as it’s always up to engineer whether to follow the agreement or break barriers and import, for example, a DAO into the REST service. Typically Java application is a number of .jar files piled up in the classpath, loaded with the same class loader, so that constructs like Class.forName() can be used freely – which is done frequently in frameworks. In other words – though in theory application is modular, in practice all classes are accessible everywhere.
In OSGi we have a framework – implementation of the OSGi specification, which serves as an underlaying base for your application. It manages the building blocks of any OSGi application – bundles. Each bundle is a .jar file with additional OSGi-related headers in the manifest. I’ll mention “Export-Package”/“Import-Package” – this pair is used to explicitly define packages exported/imported by your bundle. This means that there is no way for the client code to get access to packages of your bundle which you’ve decided to hide from the outside world. This also means that you have precise control on libraries/parts of your application available for use in each bundle, avoiding “dependencies hell”.
Second part of the modularity mechanism, and I should say the most important one, is a class loading scheme, where each bundle is loaded by its own class loader. I suggest you to think about the differences between this approach and a standard Java one yourself.
This is what exactly makes bundles dynamic entities – OSGi framework not only forces and controls modularity, but manages the state of each bundle in a standard way, also providing you an API for this so that you can control parts of your application either from the code or remotely. OSGi bundle can be in one of 6 states: INSTALLED, RESOLVED, STARTING, ACTIVE, STOPPING, UNINSTALLED. Transitions between states are controlled and allowed/rejected by the framework. What this means from the practical perspective is that you are able to dynamically extend/shrink functionality of your system, update parts of your application in run time.
Based on Modularity and Lifecycle Management OSGi provides a flexible application programming model – a so called Service Layer. Bundles can provide or consume services. Framework provides a Service Registry, where service providers register their services and service consumers search for the services. Important thing is that this model leads developers to an interface-based engineering. Conceptually services are represented as interfaces with strictly defined contracts so that there can be several implementations of the same service in the system for you to choose between. OSGi provides several APIs to work with services: from the low-level programmatic Service Tracker to a high-level Blueprint which is almost similar to Spring xml-based configuration. If you prefer annotations, then you can use Declarative Services.
Of course, this is not the whole OSGi, but these are the base architectural principles each OSGi framework is built around. It’s worth mentioning that OSGi provides rich standard functionality out-of-the-box, for example, Event Admin service for passing events between bundles, Configuration Admin for run-time configuration of bundles and so on. Some OSGi containers provide even broader additional functionality for convenient building of enterprise applications around them.
As a resume I want to say that OSGi is definitely a powerful tool for building modular dynamic applications, but reverse side is that you should learn this tool, understand deeply its specifics and get used to it. If you think you can start using OSGi in “Cavalry assault” style, then you should better not even try or there will appear one more post like this: OSGi? No, thanks
Good luck, meet you in the next post on the subject.