The OSGi technology is a set of
specifications that define a dynamic component system for Java.
These specifications enable a development model where an application is
composed of several components which are packaged in bundles.
Components are communicating through nano-services.
Components are the
reusable building blocks, provide
the implementation code, should be reusable.
The OSGi
specifications enable components to hide their implementations from other
components while communicating through nano-services, which are objects that
are explicitly shared between components
The OSGi
specifications enable components to hide their implementations from other
components while communicating through nano-services, which are objects that
are explicitly shared between components
In a well designed
OSGi system, all links between components go through a nano-service. Nano
services have an API that is defined in a Java package. The API consists
of a classes and/or interfaces that are needed for the collaboration between
the provider of the service and the consumer of the service
A Bundle is the OSGi
name for a module.A Bundle will express what Java packages it needs in
what version
Component
Systems
We wanted an
application to emerge from putting together different reusable
components that had no a-priori knowledge of each other. Even harder, we wanted
that application to emerge from dynamically assembling a set of components
For example, you have
a home server that is capable of managing your lights and appliances. A
component could allow you to turn on and off the light over a web page. Another
component could allow you to control the appliances via a mobile text message.
The goal was to allow these other functions to be added without requiring that
the developers had intricate knowledge of each other and let these components
be added independently.
OSGi
Layering
The OSGi has a layered
model that is depicted in the following figure.
The following list
contains a short definition of the terms:
- Bundles
– Bundles are the OSGi components made by the developers.
- Services
– The services layer connects bundles in a dynamic way by offering a
publish-find-bind model for plain old Java objects.
- Life-Cycle
– The API to install, start, stop, update, and uninstall bundles.
- Modules
– The layer that defines how a bundle can import and export code.
- Security
– The layer that handles the security aspects.
- Execution
Environment – Defines what methods and classes are available in a specific
platform.
These concepts are more
extensively explained in the following sections.
Modules:
In
Java terms, a bundle is a plain old JAR file. However, where in standard Java
everything in a JAR is completely visible to all other JARs, OSGi hides
everything in that JAR unless explicitly exported. A bundle that wants to use
another JAR must explicitly import the parts it needs. By default, there is no
sharing.
Though the code hiding and
explicit sharing provides many benefits (for example, allowing multiple
versions of the same library being used in a single VM), the code sharing was
only there to support OSGi services model
Nano-Services
A bundle can create an object and
register it with the OSGi service registry under one or more interfaces. Other
bundles can go to the registry and list all objects that are registered under a
specific interfaces or class. For example, a bundle provides an implementation
of the
DocumentBuilder
. When it gets started, it
creates an instance of its DocumentBuilderFactoryImpl
class and registers it with the
registry under the DocumentBuilderFactory
class. A bundle that needs a DocumentBuilderFactory
can go to the registry and ask for all
available services with the DocumentBuilderFactory
class. Even better, a bundle can wait
for a specific service to appear and then get a call back.
A bundle can therefore
register a service, it can get a service, and it can listen for a service to
appear or disappear. Any number of bundles can register the same service type,
and any number of bundles can get the same service. This is depicted in the
following figure.
This in general called a
broker pattern.
What happens when multiple bundles
register objects under the same interface or class? How can these be
distinguished? First, in many cases it is not important to distinguish between
individuals. Otherwise, the answer is properties. Each service registration has
a set of standard and custom properties. A expressive filter language is
available to select only the services in which you are interested. Properties
can be used to find the proper service or can play other roles at the
application level.
Services are dynamic. This
means that a bundle can decide to withdraw its service from the registry while
other bundles are still using this service. Bundles using such a service must
then ensure that they no longer use the service object and drop any references.
We know, this sounds like a significant complexity but it turns out that helper
classes like the Service Tracker and frameworks like Declarative Services can
remove the pain while the advantages are quite large. The service dynamics were
added so we could install and uninstall bundles on the fly while the other
bundles could adapt. That is, a bundle could still provide functionality even
if the Http Service went away.
Standard
Services
Though the service registry accepts any object as a service, the best way to achieve reuse is to register these objects under (standard) interfaces to decouple the implementer from the client code. This is the reason the OSGi Alliance publishes the Compendium specifications. These specification define a large number of standard services, from a Log Service to a Measurement and State specification. All these standardized services are described in great detail.
Declarative Services
& Configuration
Two of those standardized
services in the OSGi are the Configuration Admin service and the Declarative
Services. Though these service are just a few of the many compendium services
they have a special role. These services provide functionality that is very
hard to evaluate from the outside because they have no counterpart in in other
systems. (A case could be made that they should probably have been part of the
framework.)
Declarative Services makes
writing a service implementation as simple as writing a POJO with a few annotations.
Though there are other systems that do similar injections as Declarative
Services, these other systems ignore time and dependencies. By handling time
and (dynamic) dependencies without any code overhead OSGi provides a toolbox
that is as innovative as objects were in the nineties.
Deployment
Bundles are deployed on an
OSGi framework, the bundle runtime environment. This is not a container like
Java Application Servers. It is a collaborative environment. Bundles run in the
same VM and can actually share code. The framework uses the explicit imports
and exports to wire up the bundles so they do not have to concern themselves
with class loading. Another contrast with the application servers is that the
management of the framework is standardized. A simple API allows bundles to
install, start, stop, and update other bundles, as well as enumerating the
bundles and their service usage.
Implementations
The OSGi specification
process requires a reference implementation for each specification. However,
since the first specifications there have always been commercial companies that
have implemented the specifications as well as open source implementations.
Currently, there are 4 open source implementations of the framework and too
many to count implementations of the OSGi services. The open software industry
has discovered OSGi technology and more and more projects deliver their
artifacts as bundles