< Navigating OSGi - Extending Your Software to Embed an OSGi Framework

Navigating OSGi - Extending Your Software to Embed an OSGi Framework


Dec 12, 2017

Navigating OSGi - Extending Your Software to Embed an OSGi Framework

Navigating Open Sea_OSGI Blog Header

You have your software in place, but you need a better way of allowing your technical users to extend the platform. Most Java developers are aware of OSGi, but embedding an OSGi framework into your product seems like a huge undertaking. Further clouding the path is the uncertainty of exactly how OSGi works. For many Java developers OSGi feels more like trying to navigate the open sea rather than something they would want to play with.

Why Use OSGi within my Existing Software?

Some of the primary reasons to embed OSGi within your application is so that developers can:

  • Deploy functionality at runtime without having to stop the primary application
  • Run multiple versions of the same library, at the same time, within the same JVM
  • Separate and protect plugins from the core functionality and classpaths

Which Library to Use?

We, at dotcms, decided to use Apache Felix. The Equinox Eclipse project is also a solid option depending on what you are looking to do. Felix stays pretty close to the latest spec but both libraries have similar feature sets. In addition, Felix is better built to be embedded into an existing WAR. Both Equinox and Felix can do this but Equinox recommends, by default, embedding your server into Equinox, not the other way around.

eclipse screen grab

This is how Eclipse runs, which is what Equinox is primarily built for, so this makes sense.

If you use Jboss or Weblogic you can use the OSGi implementations they ship with, but we prefer to remain more agnostic and not rely on the underneath app server for something like OSGi.  As of the writing of this article, none of the other major implementations implement OSGi framework spec 6.

For more info see:


How to Embed OSGi

At dotCMS we were faced with the issue of needing to provide our users with the ability to deploy what we call Dynamic Plugins. A Dynamic Plugin is a plugin that can be deployed and undeployed at runtime, meaning without a server restart. The plugins needed to be able to override current functionality as well as add new functionality to our existing WAR. This involves adding Servlets, Spring Containers, Filters, Java Classes, REST Endpoints, etc.

In our case, we weren’t starting a new project where the entire app would be centered around OSGi (i.e. Eclipse), we already had an existing WAR on which we needed to add OSGi.

The great news is that OSGi is not difficult to embed. Essentially it boils down to the config and code example shown below.

First you need to add the library dependency to your project. This would be adding the JARs for either Apache Felix or Eclipse Equinox. Next you need something to start OSGi. Being a web application, we used a listener:


As an example consider the following:

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.felix.framework.FrameworkFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.launch.Framework;
public class OSGiListener implements ServletContextListener {

    private final String OSGi_LOAD_DIRECTORY = "/path/to/OSGi/bundles";

    public void contextInitialized(ServletContextEvent servletContext) {

        Map<String, String> osgiConfig = new HashMap<>();
        osgiConfig.put(Constants.FRAMEWORK_STORAGE, "/path/to/OSGi/cache");
        osgiConfig.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");
        try {
            FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class)
            Framework framework = frameworkFactory.newFramework(osgiConfig);

            BundleContext bundleContext = framework.getBundleContext();
            BundleManager bundleManager = new BundleManager(bundleContext);
        } catch (Exception ex) {
            System.out.println("OSGi Failed to Start");
    public void contextDestroyed(ServletContextEvent arg0) {
        // stop framework
    public class BundleManager {
        private BundleContext bundleContext = null;
        public BundleManager(BundleContext bundleContext) {
            this.bundleContext = bundleContext;
        public void load() throws Exception {

            ArrayList<Bundle> availableBundles = new ArrayList<Bundle>();
            //get and open available bundles
            for (URL url : getBundles()) {
                Bundle bundle = bundleContext.installBundle(url.getFile(), url.openStream());

            //start the bundles
            for (Bundle bundle : availableBundles) {
                try {
                } catch (Exception ex) {
                    System.out.println("Failed to start bundle " + bundle.getSymbolicName());

        private List<URL> getBundles() {
            List<URL> bundleURLs = new ArrayList<>();
            //load into bundleURLs the URLS for OSGi_LOAD_DIRECTORY
            return bundleURLs;

For more information see the following links:



What We Learned

  • BND is your friend. BND http://bnd.bndtools.org is a library to help you build OSGi plugins.
  • The default Gradle plugin for BND stinks. I would recommend looking at this library https://plugins.gradle.org/plugin/biz.aQute.bnd for building BND plugins. I find Gradle good for OSGi plugins, just not its default plugin.
  • Keep OSGi libraries separate from your Web App underneath. When we first got into OSGi, we provided all the libraries we had on the classpath to OSGi. Felix has a mechanism for exporting the libraries to the OSGi bundles. In hindsight, we learned that it is best for bundles to provide their own libraries or to use services from other bundles. This keeps things clean and easier for development.

OSGi is a great way to allow developers to deploy new functionality in an existing web application while keeping it protected and separate from other things within the main application. Following the instructions above, and heeding our lessons learned, it is not difficult to embed OSGi within your own application.

Recent Posts

6 Ways to Collect Accurate Voice of The Customer Data

The voice of your customer is the key to a successful customer experience orchestration strategy. Period. Here’s how to collect VoC data and avoid inaccuracies in the process.

The Benefits of Containers: Security, Speed & Microservice Compatibility

Wondering about the benefits of containers? Here’s what all the hype is about.

Website Accessibility Checklist: 10 Steps Towards Website Compliance

Website accessibility is a legal obligation in some industries, and an ethical practice in all industries. Here’s how to take your first steps towards website compliance.

3 Ways IoT Devices Can Streamline Your Customer Experience

Your customer experience may be personalized and well orchestrated across multiple channels — but with speed meaning more to the average consumer than ever before, is your customer experience fast enough?