OSGi = The Open Services Gateway Initiative defines an architecture for developing and deploying modular applications and libraries.

The Open Services Gateway Initiative (OSGi), also known as the Dynamic Module System for Java, defines an architecture for modular application development. OSGi container implementations such as KnopflerfishEquinox, and Apache Felix allow you to break your application into multiple modules and thus more easily manage cross-dependencies between them.

OSGi offers the following advantages:
  • You can install, uninstall, start, and stop different modules of your application dynamically without restarting the container.
  • Your application can have more than one version of a particular module running at the same time.
  • OSGi provides very good infrastructure for developing service-oriented applications, as well as embedded, mobile, and rich internet apps.

Open source OSGi containers

From an enterprise developer's point of view, the OSGi container has such a low footprint that you can easily embed it into an enterprise application. For example, let's say you're developing a complex Web application. You want to break the application into multiple modules: one module for the view layer, another for the DAO layer, and a third module for the data access layer. Using an embedded OSGi container to manage the cross-dependencies of these modules would enable you to update your DAO layer (say from slow DAO to fast DAO) without restarting your application.

OSGi bundle

In OSGi, software is distributed in the form of a bundle. A bundle consists of Java classes and other resources that deliver functions to device owners, as well as providing services and packages to other bundles. If your bundle needs to be notified at the time of bundle startup or shutdown then you should create a class implementing the BundleActivator interface. 

OSGi commands

Here are some of the commonly used OSGi commands that you can use to interact with your OSGi container:
  • ss displays a list of installed bundles with the status of each bundle. It will display the bundle ID, short name, and status of the bundle.
  • start <bundleid> starts a bundle.
  • stop <bundleid> stops a bundle.
  • update <bundleid> updates a bundle with a new JAR file.
  • install <bundleURL> installs a new bundle into the OSGi container.
  • uninstall <bundleid> uninstalls already installed bundles from the OSGi container.

Dependency management

The OSGi specification allows you to break your application into multiple modules and then manage their dependencies on each other. It does this by adding a bundle scope. By default, none of the classes in a bundle are visible from any other bundle; inside bundles they follow the normal rules of the Java language. So, what do you do if you want to access the classes of one bundle from another bundle? The solution is to export packages from the source bundle and then import them into the target bundle.
How is the OSGi container able to hide a few classes from the .jar file while others are visible? The answer is that the OSGi container uses the Java class loader to manage class visibility. The OSGi container creates a different class loader for every bundle. The bundle can therefore access classes from
  • Boot classpath: Contains the java.* packages.
  • Framework classpath: Usually has a separate class loader for the framework implementation classes as well as key service interface classes.
  • Bundle space: Consists of the JAR file that is associated with the bundle plus any additional JARs that are closely tied to the bundle, like fragments.
  • Imported packages: For instance, the HelloWorld bundle imports the com.javaworld.sample.service package so it can access classes from that package.

OSGi services

As previously mentioned, the OSGi architecture is a very good candidate for implementing service-oriented applications. It allows bundles to export services that can be consumed by other bundles without knowing anything about the exporting bundle. Taken with the ability to hide the actual service implementation class, OSGi provides a perfect combination for service-oriented applications.
In OSGi, a source bundle registers a POJO (you don't have to implement any interfaces or extend from any superclass) with the OSGi container as a service under one or more interfaces. The target bundle can then ask the OSGi container for services registered under a particular interface. Once the service is found, the target bundle binds with it and can start calling its methods. As with other OSGi concepts, a sample application will make all of this more clear.
BundleContext.registerService() 
method to export the service. It takes three parameters:
  • The name of the interface under which you want to register the service. If you want to register the service under multiple interfaces then you should create a String array of interface names and pass it as your first argument. In the sample code we want to export the service under the name of HelloService interface.
  • The actual Java object that you want to register as a service. In our sample code we are exporting objects of the HelloServiceImplclass as the service.
  • Properties of the service, in this case a Dictionary object. If more than one bundle exports a service under the same interface name then the target object can use these properties to filter out the service that it is interested in.