OSGi (Open Services Gateway initiative) fundamentals

Amalanathan Thushanthan
5 min readJun 26, 2019

Let's consider this complex architecture,

In the developer perspective, it is hard to understand what is happening here?. At the same time, we can not do any modification on the code level as we like because some classes internally depend on other classes.

Do you believe that there is a single solution will solve all the issues mentioned above? Yes, OSGi service will solve all of these issues.

Before going into deeper we go through some basic concepts that help to understand more about OSGi.

Modularity

Modularity is not something new, simply says other than writing a complex program divide the program into small chunks and put some borders according to their functionality and dependencies. Each divided chunks call as an independent module.

Within the module, we can have multiple classes based on the module functionality. The module can able to decide which classes need to be available for public usage and which are private (means which can be used by other modules).

In here, we can easily understand the concept of the program, like which module is responsible for which purpose. Also, we can do the modification at any place that we want and we can reduce the coupling issues.

On the other hand, we can deploy and test the program separate and independent manner.

OSGi service deploys based on the Modularity.

Let's have a brief look at what is OSGi and OSGi architecture.

What is OSGi?

The OSGi specification is developed by the members in an open process and made available to the public free of charge under the OSGi Specification License. It is a Java framework for developing and deploying modular software programs and libraries. Each bundle is a tightly coupled, dynamically loadable collection of classes, jars, and configuration files that explicitly declare their external dependencies (if any). <wiki>

As we mentioned above, OSGi based on the Java framework for developing and deploying modular software programs and libraries. ie) we can install, uninstall, start, stop and updates in the form of bundles for deployment without a restart. Also, we have many well known and predefined OSGi container infrastructure such as Equinox, Knopflerfish, Apache Felix etc.

OSGi is a layered architecture. There are six primary layers in the OSGI architecture.

  • Bundles: It is responsible for packaging the software components as jar archives with metadata.
  • Services: These are responsible for interact and communicates between bundles.
  • Service registry: These are clearly defined method for managing communication among various services.
  • Life Cycle: It defines how the bundles are dynamically installed and manage in the OSGi framework.
  • Modules: It defines the declaration of dependencies (how a bundle can import and export code).
  • Security: It is responsible for handles the security aspects by limiting bundle functionality to pre-defined capabilities.

Bundles

The software components of an OSGi framework are called bundles. The bundle packed as a jar archive. It is the collection of Java class files, resource files (icons, XML and HTML files), and the metadata (manifest file). In addition to that, a bundle can have other jar archives that used as input libraries.

The bundle manifest file is the one differentiate the bundle from normal jar archives. The bundle manifest contains important information related to the corresponding bundle like bundle name, version number, import and export packages, etc.

sample manifest.mf file

Services

The services help to interact between bundles. i.e) service provider bundles publish their available public services from the service registry. The services can publish from the service registry with one or more interface names. Then the service requester bundles who need that services can search the services using interface name and get it from the service registry.

Life Cycle

The Life cycle briefly describes how bundles are dynamically installed and manage in the OSGi framework. It allows the user dynamically administrate to installed, started, stopped, and uninstalled independently from the life cycle of the JVM. Also, bundles can safely add and remove from the framework whenever they want without restart the server.

At the initial point, the life cycle starts with installed bundles. After that life cycle layer ensures that all their dependencies are resolved because of avoiding the exception like ClassNotFoundException at run time. After the resolved check it moves to the basic flow as Start the bundle then active it and finally stop. If the life cycle layer finds any unresolved dependencies then the OSGi framework reports the issue and life cycle layer stops at that point and never goes to the starting state.

Each bundle can provide a bundle activator class that the framework calls as part of bundle start and stop events.

Here is an activator.class sample.

package com.hazelcast.internal.osgi;

import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.logging.ILogger;
import com.hazelcast.logging.Logger;
import java.lang.reflect.Method;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {
private static final String HAZELCAST_OSGI_START = "hazelcast.osgi.start";
private static final ILogger LOGGER = Logger.getLogger(Activator.class);
private HazelcastInstance hazelcastInstance;

public Activator() {
}

public void start(BundleContext context) throws Exception {
this.activateJavaxScripting(context);
if (Boolean.getBoolean("hazelcast.osgi.start")) {
this.hazelcastInstance = Hazelcast.newHazelcastInstance();
}

}


public void stop(BundleContext context) throws Exception {
if (this.hazelcastInstance != null) {
this.hazelcastInstance.shutdown();
}

}


private void activateJavaxScripting(BundleContext context) throws Exception {
if (!this.isJavaxScriptingAvailable()) {
LOGGER.warning("javax.scripting is not available, scripts from Management Center cannot be executed!");
} else {
Class<?> clazz = context.getBundle().loadClass("com.hazelcast.internal.osgi.ScriptEngineActivator");
Method register = clazz.getDeclaredMethod("registerOsgiScriptEngineManager", BundleContext.class);
register.invoke(clazz, context);
}
}

private boolean isJavaxScriptingAvailable() {
try {
Class.forName("javax.script.ScriptEngineManager");
return true;
} catch (ClassNotFoundException var2) {
return false;
}
}
}
  • ************************** END *****************************

📝 Read this story later in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--