OSGi Component Framework Basics
The Open Service Gateway initiative (OSGi) commonly refers to a standard specifying a Java-based service platform that can be remotely managed. The core part of the specifications is a framework that defines an application life cycle management model, a service registry, an Execution environment and Modules (see Wikipedia entry on OSGi). There are currently five certified implementations complying to OSGi specification R4, including Eclipse Equinox and Knopflerfish.
As component frameworks, OSGi implementations provide a way to encapsulate and package functionality into well-defined packages. In this case, the packages correspond to bundles, which can import and export services as a way of interacting with other bundles. These bundles are packaged in JAR files which enclose the Java classes of the implementing code, along with the required metadata (i.e., the MANIFEST file).
Components and Services
Before we delve into the core of OSGi installation and use, we need to provide some additional explanation as per the motive for OSGi. Since the early 70's, computer scientists realized the importance of encapsulation (see this classic work from Parnas for example).
Encapsulation allows implementing complex software with only a small fraction of it (the API) exposed to its users. This makes it possible to edit and update the internal implementation of the software without requiring any action from its users. In its most modern form, encapsulation (or information hiding) is enabled using components and services.
One of the most popular definitions of software components specifies them as "[software components] are units of composition with contractually specified interfaces and explicit context dependencies only; [software components] can be deployed independently and is subject to composition by third parties" (Component Software - Beyond Object-Oriented Programming book). On the other hand, services are used to indicate a predefined set of functionality through an interface (functional logic) along with some policies and/or contracts defining its extra-functional properties, such as Quality of Service (QoS) contracts, etc.
In OSGi, encapsulation is achieved via software components and services. The former can register (i.e., provide) or use (i.e., consume) services dynamically, as needed. Services allow loose coupling of components, i.e., the service providers do not know about their users and the service users do not know about their providers. Notably, in OSGi the coupling is done dynamically (i.e., at runtime) which provides much more functionality and reliability to the systems.
Downloading and Installing the Framework
While there are multiple implementations of the OSGi specification, for the purposes of this tutorial we will use Eclipse's Equinox.
Your first step is to download Equinox. At the time of writing this tutorial, version 3.4.1 is the latest one, and is available for download at this link.
Once it is downloaded, you should unzip the file to the folder of your choice (e.g., in "c:\", which creates the "c:\eclipse\..." folders).
The core of the Equinox implementation of OSGi is in the "plugins" folder, in a JAR file named "org.eclipse.osgi_3.4 ... .jar". Copy that file to "c:\" and rename it to "equinox.jar".
Starting the OSGi Console
To start the (console view) of the framework, simply issue the following command:
C:\eclipse>java -jar equinox.jar -console
osgi>
The framework is up. You can issue your first command to the console. Try "help" or "ss". The first one prints a list of available commands. The second one, shows the short status of the framework, as in the following:osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230
This output says that there is only one bundle installed in the framework (the core OSGi implementation by Equinox), which is assigned the ID "0" and is currently "active". Each bundle can be further introspected with the "bundle" command, as follows:osgi> bundle 0
System Bundle [0] Id=0, Status=RESOLVED
Registered Services {org.eclipse.osgi.framework.console.CommandProvider}={service.ranking=2147483647, service.id=1} {org.eclipse.osgi.framework.log.FrameworkLog}={service.ranking=2147483647, service.pid=0.org.eclipse.core.runtime.adaptor.EclipseLog, service.vendor=Eclipse.org, service.id=4} {org.eclipse.osgi.framework.log.FrameworkLog}={service.ranking=-2147483648, performance=true, service.pid=46org.eclipse.core.runtime.adaptor.EclipseLog, service.vendor=Eclipse.org, service.id=5} {org.eclipse.osgi.service.runnable.ApplicationLauncher}={service.id=22}
Services in use: {org.eclipse.osgi.framework.console.CommandProvider}={service.ranking=2147483647, service.id=1}
No exported packages [PackageAdmin service is not registered]
As it was already mentioned in the OSGi Basics, bundles interact with each other via services. In this case, the services are abstracted and correspond to plain Java Interfaces. As such, each bundle specify a list of offered (i.e., registered) and needed (i.e., used) services. Notably, this status shows that the Equinox bundle offers (and uses) the "org.eclipse.osgi.framework.console.CommandProvider" interface. This is a service which allows interfacing with the Command Line Interface (i.e., the console), and it will be revisited in one of the following tutorials.Getting ready for Declarative Services
While the current bundle is sufficient for the core OSGi, additional bundles are needed in order to add more functionality. For example, in order to deploy bundles which use Declarative Services, you need to install the following bundles: "org.eclipse.equinox.ds_1. ... .jar", "org.eclipse.equinox.util_1. ... .jar" and "org.eclipse.osgi.services_3. ... .jar".
Please note that all the needed JAR files are available in the "./plugins" folder, and they can be installed by referencing them directly as follows:
osgi> install file:plugins\org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar
Bundle id is 1
osgi> install file:plugins\org.eclipse.equinox.util_1.0.0.v20080414.jar
Bundle id is 2
osgi> install file:plugins\org.eclipse.osgi.services_3.1.200.v20071203.jar
Bundle id is 3
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230
1 INSTALLED org.eclipse.equinox.ds_1.0.0.v20080427-0830
2 INSTALLED org.eclipse.equinox.util_1.0.0.v20080414
3 INSTALLED org.eclipse.osgi.services_3.1.200.v20071203
osgi> start 1
osgi> start 2
osgi> start 3
osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.4.2.R34x_v20080826-1230
1 ACTIVE org.eclipse.equinox.ds_1.0.0.v20080427-0830
2 ACTIVE org.eclipse.equinox.util_1.0.0.v20080414
3 ACTIVE org.eclipse.osgi.services_3.1.200.v20071203
Finally, please note that after you install a bundle, it is copied in "./configuration" (which is created by OSGi the first time you launch it) and thus it is not needed to keep it at the source folder anymore.In this case, we have started all the bundles and executed the short status (ss) command afterwards.
Shutting the OSGi console down
To exit the console, you can simply issue the "shutdown" command followed by "exit" command:
osgi> shutdown
osgi> ss
Framework is shutdown.
id State Bundle
0 RESOLVED org.eclipse.osgi_3.4.2.R34x_v20080826-1230
osgi> exit
Homework 1.1: Run the "help" command in the console. Report what each of the following commands does:
- status
- diag ID
- h ID
- services
- packages
- close
