In this section you'll find out what OSGi actually is, what you can do with it, and what it can bring to your development infrastructure. OSGi is a modular runtime for applications requiring a life cycle, deployment into a running container as well as re-use of services and libraries. OSGi is often seen as being complex, with many tooling and classloading issues. Our goal is to show you how to overcome these issues which are often misconceived. If you take the time up front, building applications is actually quite simple.
The basic function of OSGi is to provide Java developers with a component model that regulates code identity, versioning, interaction between code, life cycle, and making code requirements strictly enforceable. This model is encapsulated by its three key aspects; bundles, life cycle, and services—all within a single OSGi container. See the OSGi home page http://www.osgi.org/Specifications/HomePage for the full specification. OSGi is a very mature standard; the original OSGi Service Gateway Specification Release 1.0 was released in May 2000. The key architectural aspects of OSGi that we will be focusing on is shown in the following diagram:
OSGi allows you to create dynamic, live architectures and applications.
Starting with bundles, developers are able to encapsulate functional portions of code into single deployable units, with explicitly stated imported and exported packages. This allows for simplified management since the bundle has a clear function and environment. A bundle is a jar with additional information. This information allows you to control what packages are imported, exported, as well as which ones are private and/or hidden. In contrast to a regular classloading environment, you as a developer can control explicitly what you expose, share, and how it is versioned.
It also motivates you as a developer to build distinctly identifiable JAR files, small sets of code that do a few things in a clearly defined manner.
OSGi provides these bundles with a life cycle. Despite OSGi's age, it is still one of the few plugin solutions that actually implement this correctly, allowing you to load and unload as you need. Once a bundle is resolved it can be freely started or stopped, updated, or removed remotely via an API. The framework handles the heavy lifting, ensuring that an installed bundle has all of its requirements met. The following screenshot shows Apache Karaf which wraps an OSGi core, providing developers with a simple interface to manage their OSGi applications:
Finally, OSGi allows developers to take advantage of micro-services; these are services provided by one bundle to another in a dynamic fashion. As bundles come and go in the framework, the wiring between service producers and consumers is managed such that bundles adapt to the changing environment. This is a very empowering feature indeed, allowing developers to build nearly organic architectures that evolve after initial deployment at runtime, not to mention a holy grail of factory patterns for applications that need to grow.
OSGi is best used with applications designed using modular programming principles; however, your existing Java-based applications can take advantage of OSGi. When we look closer at OSGi applications we'll see that very little or no additional code is required to make aspects of OSGi available to your application. The essential addition is a few extra headers added to Java Archive manifest files. These headers are used to identify the bundle, its version, its imported dependencies from the environment, and any exported packages the bundle provides. In fact, just adding these few OSGi headers to a JAR manifest will create a valid OSGi bundle. To take advantage of more advanced OSGi features, however, we'll have to introduce some additional code; luckily the additions will not introduce a heavy burden on developers. Let's continue onwards and explore how to set up an OSGi environment, then we'll dive into building a complete OSGi application.