Undestanding Java OSGI framework
Tags: osgi, java, standalone
Published: 2021-09-22 03:46:25

---
title: Undestanding Java OSGI framework
published: true
description: what is OSGI framework and how it worked
tags: osgi, java, standalone
cover_image: https://images.freeimages.com/images/large-previews/21d/digital-dreams-1155366.jpg
---

OSGI is a framework used in building complex Java applications that contain multiple components. With OSGI, you can build Java application that can load dynamically. When you are building a basic Java application, you might create a jar file for each module and load it with the class path. But, with the OSGI framework, you can load OSGI jar file dynamically whenever you needed.
Lets discuss some of the terminologies and concepts that you should know about OSGI framework:
## Bundle
Bundle is the OSGI module that contain all your logics. Bundle is a jar file that contain your business logic that provide some service. Other than a regular jar file, it also contain information about how it supposed to work in OSGI runtime in MANIFEST.MF file. These information include a bundle name, version, exported and imported libraries.
Following is a sample definition of OSGI bundle definition:
```
 Bundle-Name: Hello World
 Bundle-SymbolicName: org.dhanushka.helloworld
 Bundle-Description: A Hello World bundle
 Bundle-ManifestVersion: 2
 Bundle-Version: 1.0.0
 Bundle-Activator: org.dhanushka.Activator
 Export-Package: org.dhanushka.helloworld;version="1.0.0"
 Import-Package: org.osgi.framework;version="1.3.0"
```
- **Bundle-name** is used to identify the bundle. This is just a optional string value.
- **Bundle-SymbolicName** is a unique identifier for the bundle. This follows the common java package naming standard.
- **Bundle-Description** is a description about what this bundle does.
- **Bundle-ManifestVersion** is versioning used by OSGI framework to read bundle manifest.
- **Bundle-Version** is the version number you allocated for the OSGI bundle.
- **Bundle-Activator** is the starting point of your module. You bundle can have multiple class implementations. OSGI use this property to mark what is the class that used as starting point of the bundle. We will discuss about bundle activator more later.
- **Export-Package** is a set of packages that you need to expose to other OSGI bundles. If you didn't specify export packages, then other OSGI bundles unable to access classes in your OSGI bundle.
- **Import-Package** is a set of packages that required to your OSGI bundle. You should import packages in here if you need to refer any other OSGI bundles.

Bundle is simply a module that contain all of your programming logics. You can import another bundle functionality into it and expose your own functionality to other bundles.

## Services
Services are the way how each of the bundles are connected together. As I have already explained, multiple bundles can be connected together to provide some service.
Check the following sample bundle implementation that has activation method on it:
```java
public class Activator implements BundleActivator {
	private BundleContext context;

	@Override
	public void start(BundleContext context) throws Exception {
		System.out.println("Starting");
		this.context = context;
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		System.out.println("Stopping");
		this.context = null;
	}
}
```
In this source code, the bundle activator is the `Activator` class. When the OSGI starting up it start executing the `start` method. This is much similar to the `main` method. When the OSGI framework stopping, it trigger the `stop` method. Whenever you add this bundle into the OSGI runtime, it will start execution by calling the `start` method and end its execution by calling the `stop` method.
As you can see, this bundle does not have any dependency with other OSGI bundles. It can start its execution independently. In some scenarios, you might need to start this bundle when some conditions are met. Until condition satisfy, OSGI runtime does not call the `start` method.
This can be achieved with references. References let you to call `start` method once given conditions are met. Check the following modification done to the `Activator` class:
```java
public class Activator implements BundleActivator {
	private BundleContext context;

	@Override
	public void start(BundleContext context) throws Exception {
		System.out.println("Starting");
		this.context = context;
	}
        @Reference(
            name = "activator.service",
            service = ActivatorService.class,
            cardinality = ReferenceCardinality.MANDATORY,
            policy = ReferencePolicy.DYNAMIC,
            unbind = "unsetActivatorService")
    protected void setActivatorService(ActivatorService activatorService) {
            // Set values
     }

    protected void unsetActivatorService(ActivatorService activatorService) {
            // Unset values
    }

	@Override
	public void stop(BundleContext context) throws Exception {
		System.out.println("Stopping");
		this.context = null;
	}
}
```
In this code, other than previous `start` and `stop` method, there are another two methods. `@Reference` annotation used here to mark these dependencies. Here, we have given a service name and service class. Under the reference annotation, we defined the `cardinality` as mandatory. Since the cardinality marked as mandatory, to trigger `start` function, `setActivatorService` should be satisfied. If the cardinality is optional, then it is not mandatory to call `setActivatorService` to start this bundle. This method can be triggered from another bundle. Following is a sample code, how to trigger `setActivatorService` method.
```
context.getBundleContext().registerService(ActivatorService.class.getName(), activatorService, null);
```
Here, the `activatorService` is the object that contain details that need to send to the `setActivatorService`. Once this method get called, OSGI bundle will start the `ActivatorService` `start` method.

You can build more advanced applications by using the OSGI framework. You build dynamically pluggable components with dependency injection design pattern.