Software development is no longer a finite or static process. Software development is now rather a continuous process of extensions and evolution.
This article is targeted at developers of desktop applications that need a better software development and distribution system. There are a number of good commercial distribution tools, one standout example is Bitrock’s InstallBuilder. This tool allows you to create installers that allow you to bundle a runtime for target applications, however there are many small details to overcome that are system and hardware dependent.
Another critical area where problems emerge is when you need to distribute updates. Installbuilder has an automatic update feature which is would be driven by implementing a remote server. Issues will also emerge when a project has complex changing dependencies.
While commercial tools like InstallBuilder go a long way to deal with the development and distribution issues, an alternative Open Source solution that at least in the Java Virtual Machine based language world is has always been an Industry standard is the Open Service Gateway Initiative (OSGI) specification.
In a Operating System (OS), programs interact with each other while running on a machine, using a kernel to coordinate everything, programs communicate via ports and sockets that are bound to daemons and services.
For OSGI and Java we can loosely think of the machine as the “JavaVM”, the daemons as “modules”, the applications “bundles”, and the ports “interfaces”. The OS acts as the “services registry” by coordinating everything. The critical concept is that OSGi was designed to be suitable for machines with minimal OS such as a bare metal hypervisor. A good example of this is the IBM commercial product WebSphere Application Server Hypervisor Edition. It is Java/OSGi-based platform created from a minimal GNU/Linux distribution and an IBM JDK. When you boot up the hypervisor, everything possible is done in Java.
OSGi is designed to be dynamic; in a running framework bundles can be added, removed and updated. Combined with an IDE that understands this, we can make updates to a running application without ever waiting for builds or restarts.
Services based architecture
OSGi applications are composed of bundles (components). A common approach when designing an OSGi application is to follow an API pattern based on providers and consumers. The diagram below shows an API bundle, an implementation bundle providing a service, and a client bundle that consumes the service from the implementation bundle. Both the client and implementation bundles have a package dependency on the API bundle that contains the Java interface for the service.
The articles source code which you can checkout from here, is a OSGi application that follows this pattern where the API bundle, client/consumer bundle and the provider/implementation bundles are shared and provisioned from the internal bundle repository into a Apache Felix framework.
OSGi defines a dynamic service deployment framework that is amenable to remote management. An OSGi framework Application can be updated while the application is running, if you have ever installed an Eclipse plugin this is an example of this. Apache ACE is an example of a provisioning system that allows installing and updating the software running on a target device.
Installing the Example Source Code
To run the article demonstration code you need
1. Install latest gradle on path
● download and install gradle https://gradle.org/downloads
● add gradle to your path so you can run gradle commands from the terminal
2. (a) Install the OSGi build tool for eclipse BNDTools by following the instructions here
3. Import the demo code into eclipse
Browse to where you have checkout the source code from Github, select the top level directory and you should see eclipse find all the gradle modules to import as shown below.
It’s important to realise this is a gradle build, all the modules are declared in the settings.gradle as shown below
Also the correct dependencies need to be declared in the build.gradle as shown below
By inspecting the demo codes build.gradle you can see how the bnd workspace is configured. The screenshot below shows the correctly configured gradle artifacts and osgi bundles in eclipse after a successful import.
Running the Example Source Code
To run the application in eclipse, open (double click) the ‘demo.bndrun’ file in the run module. Select the Run OSGi button shown at the top right in the screen shot below. By typing ‘lb’ in the Apache Felix Gogo shell that opens when the application runs you can see the active bundles.
Overview of the Source Code
The Bundle Symbolic Name is used by the OSGi runtime to uniquely identify a bundle. The demo code has three public bundles.
● eduonix.osgi.democode (api bundle, defines a service)
● eduonix.osgi.mainapp (consumer bundle consumes the service)
● eduonix.osgi.maingui (provider bundle provides the service)
OSGi has the concept bundle encapsulation, in the eduonix.osgi.maingui bundle the package eduonix.osgi.mainguiimpl is declared to be private. The encapsulation parameters are set in the export declaration of the Bundle manifest as shown highlighted in blue below.
Created-By: 1.8.0_45 (Oracle Corporation)
Export-Package: eduonix.osgi.maingui;version="1.0.0";uses:="javafx.scene "
The content of the Bundle manifest enables the OSGi Framework to process the modular behaviour of the bundle at runtime.
The components of an OSGi application are bundles. Bundles act as modules. Bundles can encapsulate their internal class files from other bundles and communicate via services. An OSGi application as a result of its modularity allows for a dynamic behaviour for its components at runtime. OSGi achieves this via its Bundle manifests. Any Bundle’s manifest specifies how it is to be installed and managed. An OSGi application component can be installed, started, stopped, updated, and uninstalled while application the application is running. This solves many of the issues encountered in application provisioning.
Bundles allow the mixing and matching of components and the dependencies of components can be specified. OSQi has a well-defined dependency management model. All bundles are versioned and only bundles that can collaborate share a class space. The OSGi service registry allows bundles to register, call and listen for services. This allows bundles to discover the capabilities of the underlying system.
The demo code packages the Apache Felix implementation of the OSGi Release 4 Framework with the Apache Gogo shell, this adds about a 300 KB to the exported JAR file. This is a small overhead for the amount of functionality that is added and follows from the evolution of the framework from embedded environments.