Getting started with GWPA: OSGi Introduction
“what does OSGi mean?”
I know that it is annoying to read such abbreviations everywhere and there are many, many abbreviations and there are many, many everywhere – it is annoying as it seems that I have to know what these abbreviations mean and it seems that everybody else knows what they mean. It seems that it is only me who never remembers what these 3 or 4 characters in this special combination and order, this highly sophisticated acronym, means…
OSGi in brief
After this confusing introduction, you can calm down. In case of OSGi, it is not relevant what this acronym stands for and it isn’t even important to remember to write the i in lower case…
This means that you can forget that OSGi stands for “Open Services Gateway initiative”, which was the first name of the consortium (now called “OSGi Alliance”) which defined the OSGi specification.
The specification specifies a Software Platform.
It is based on a Java VM.
First release was in 2000.
It provides a modular dynamic component system.
The OSGi Framework supports to run many applications and services in a modular way, independent from each other, on the same virtual machine.
It allows controlling the lifecycle of these modules during runtime, this means: you can install and update and stop and start and uninstall these modules during runtime.
Dependencies between these modules and their versions are supported and can be clearly defined.
An architectural overview can be found here.
OK, I confess that it doesn’t sound as amazing as it really is.
Let’s phrase it like this:
OSGi == good
Easy to remember.
There are of course many commercial and open-source implementations of the OSGi-Framework, and Enterprise Service offerings based on OSGi.
The most interesting for us is the OSGi-Framework Equinox (open-source), which you’ve probably already heard, because it is being developed by the Eclipse Foundation.
Note that Equinox isn’t the reference implementation. It is OSGi and even a bit more. It comes with special functionality, developed for own needs, i.e. Eclipse needs (e.g. the extension point concept, which makes Eclipse so rich):
Now I’ll try to explain the basic expressions in the context of OSGi – you’ve probably heard them and were wondering about.
We have the specification of OSGi.
We have the implementation, e.g. Equinox
It is a framework, a container for hosting bundles.
On top of an OSGi container, we have an OSGi-based product like the Eclipse IDE, which adds lots of bundles on top of the framework.
Bundle is the generic term for one module (= component) running on top of the OSGi Framework.
Physically, it is a set of Java-classes and resources packed in a .jar archive.
Each bundle has its own class-loader, which allows to support different versions of one bundle in the same container.
Each bundle is isolated, self-contained, modular, but can define dependencies to other bundles (in clearly determined versions).
In order to allow to be referenced by others, a bundle can define which of its packages are public.
A bundle is defined by the MANIFEST.MF file, which is located in the META-INF folder of the bundle jar-file.
This file contains basic meta-information about the bundle, like its unique ID and its Version (which together allow to uniquely identify the bundle).
Furthermore, its dependencies and its public API.
And lots more.
And even information that can be specific to the bundle itself.
A bundle may define a Java-class, which serves as “Bundle-Activator”. Such a class allows access to the OSGi-Framework and it can control the bundle, because it will be called on start and on stop of the bundle.
Example for the content of a MANIFEST.MF file:
Bundle-Name: My Bundle One
OSGi defines 6 lifecycle phases for a bundle:
UNINSTALLED, INSTALLED, RESOLVED, STARTING, ACTIVE, STOPPING
The user or developer or the admin of an OSGi based environment can use the OSGi-console to control the status of a bundle.
The most important status information outputs are:
After deploying a bundle to the OSGi container, it is typically started immediately. Then the status is ACTIVE.
If a bundle fails to activate, it remains in status INSTALLED.
If a bundle, which is in status ACTIVE, is stopped, its status changes to RESOLVED.
OSGi provides services, these are thin Java objects, which can be used across modules.
A bundle can obtain the services that are living inside the OSGi runtime by asking the central Service-Registry.
An example for a OSGi service provided as per default could be the StartLevelService.
Bundles can as well provide own services.
A Fragment-Bundle is a special kind of bundle, which cannot live alone, but only together with a host-bundle, which has to be declared.
As such, a fragment doesn’t have an individual lifecycle.
Fragments are typically used for carrying JUnit-tests, or resource bundles (e.g. language files).
As mentioned above, the OSGi-console allows to administrate the OSGi container.
Of course, the available commands depend on the implementation of the OSGi container.
Here’s a list of common commands.
Note: where abbreviations are supported, they are added in parenthesis.
short status. Lists all installed bundles and registered services. Filter parameter can be added.
Example for listing all bundles which are in status RESOLVED:
ss -s RESOLVED
displays information about installed bundles and registered services. Supports filter parameter.
without parameter: lists all bundles
|lb||List bundle. List all bundles matching the specified filter (or all, if no filter is given).|
|bundle (b)||displays details of specified bundle|
|bundles||displays details for all installed bundles|
|packages (p)||displays details about imported/exported packages|
|se||displays details of registered services|
|gc||perform garbage collection|
|props (pr)||print system properties|
|setprop (setp)||set OSGi properties|
|threads (t)||display threads|
print bundle headers (of manifest.mf) for the given bundle
|log||log + the substring to match|
|diag||prints issues for the specified bundle|
|start||starts the specified bundle|
|stop||stops the specified bundle|
|refresh (r)||refreshes the specified bundle|
|install||install a bundle from specified location|
|uninstall||uninstalls the specified bundle|
|init||uninstall all bundles|
|exit||exit the process|
|close||shutdown and exit|
|disconnect||disconnects the connection to OSGi port|
How to install features from a p2 repository
Installing from P2 repository is done in 3 steps:
1. Add a repository to the OSGI-container
2. Install features from there
3. Apply the changes
1. Start OSGi runtime
2. Open console and connect to it via command (the port number has to be adapted):
telnet localhost 1111
3. Add the repository to the OSGI container using the command
4. Print the features to be installed
Type the following command:
The result is a list of features + versions which can be installed (contained in the added repositories)
5. Install the desired features
Copy one line from the result of step 4 to clipboard
Type the following command followed by space and add the feature + version from clipboard
provinstall <feature> <version>
provinstall com.my.company.feature.group 0.0.1
6. repeat step 5 for all the desired features
7. Save the changes
Type the following command
Note: There’s an alternative for step3:
Instead of pointing to a URL, an archive file on the local file system can be used.
Then add the repo with the same command, but using the file protocol:
Remove a repo
The following command can be used in order to remove a repository from the OSGI container:
Uninstall a feature
In order to uninstall a feature (in a given version) from the OSGI container:
type the following command in the OSGI console
Install a single bundle
In order to install a bundle, there are 2 variants:
a) Hot deployment
Copy to the respective folder, if hot deployment is supported by the OSGi container.
Examples for such folder names:
dropins or pickup
Type the following command
Uninstall a single bundle
According to the description above, there are 2 variants:
a) delete the jar from the hot-deployment-folder
b) Type the following command in order to uninstall the bundle:
OSGi in the context of Eclipse
When I started using Eclipse in the early beginning (2002), it was presented as one big archive to be downloaded.
When companies built their tools and products on it, such a product was delivered as an archive as well, but it quickly became a very huge archive.
Plug-ins were installed as folders and the folders contained a plugin.xml file which contained all metadata of the plug-in, in addition to the extension points.
All plug-ins and all of their dependencies had to be put into one installation-archive.
Everybody who installed that archive, got everything that’s inside, even if he needed only one little part of it.
After adding many plug-ins to Eclipse, the duration of the startup of such product increased heavily.
And it became hard to keep overview of all plug-ins.
Later on, Eclipse introduced the concept of features, which was already helpful.
But the big improvement came 2004 with Eclipse 3.0, when Eclipse was moved to OSGi, i.e to Equinox.
We had to refactor all our plug-ins, but it was worth it.
The installation paradigm was changed from push to pull.
From now on, users only pull those features into their Eclipse, which they are interested in.
There might be a negative impact: the user is now responsible for pulling.
This means that he has to find out the location of the features that he needs.
And this means that he might have to deal with several software locations.
But once this is done, he can enjoy the support for updates.
Who provides such support?
And here comes a new term: p2 and provisioning
In early times, the process of installation in Eclipse was:
Unzip the downloaded eclipse-zip.
In order to install new plug-ins in Eclipse: copy them into the plugins folder and restart Eclipse.
On every startup of the IDE, Eclipse had to parse all plugin-xml files, in order to know which plug-ins are part of the IDE.
Later on, Eclipse introduced OSGi and a cache. Such that only the small metadata file had to be read, and only when “Reload” was pressed (in Eclipse preference page), the plugins folder was parsed.
So the question is, how is installing and updating handled, after the move to OSGi ?
The first try was the so-called Update Manager.
With Eclipse 3.4 (Ganymede, 2008) the new concept for installation was introduced: the provisioning tool called p2
P2 is developed as part of Equinox.
P2 is a provisioning platform, used mainly for OSGi environments, but with special focus on Eclipse.
P2 includes the “director”, which is the tool that controls the provisioning, the entry point for installation.
P2 includes the “engine”, which performs the changes in the profile.
The profile is stored in the Profile-Registry, and contains the metadata of all installed “Installable Units”
Metadata are written in xml and stored in the Metadata-Repository
Artefacts are the actual bundle jar-files, and stored in the Artefact-Repository, and listed in the artefact.xml
Note that artefacts and their metadata are separated, such that procedures like installation, update, and the required dependency analysis can be calculated based on the metadata and not on local archives.
Installable Unit is the generic term, can be a bundle or a feature, identified by unique ID and version.
You may have a look into your Eclipse installation folder.
There, you’ll find a folder called p2, which itself contains the folders for the repository and the engine.
The file …\eclipse\configuration\org.eclipse.equinox.simpleconfigurator\bundles.info lists all installed plug-ins, and is altered after changes to the installation.
P2 itself is – as usual in the OSGi-World – provided as a set of features and plugins.
Adding Plugins to your Eclipse:
1) Using p2
Eclipse provides the user interface for p2 under the Help menu
The installation process will copy the bundles into the so-called “Bundle Pool”, which is the “plugins” folder in Eclipse.
2) Using the dropins folder
This folder is a “watched directory”, where you can copy plug-ins to and it will be discovered by p2.
This means that such plug-ins are really installed, dependencies or duplicates are resolved, plugins are added to the profile and can be updated via the p2 UI.
This folder is typically used by scripts during nightly build, or for quick testing of development
3) Use the plugins folder – discouraged
For compatibility reasons, plug-ins which are copied into the plugins directory, are detected on startup of eclipse.
But it is not recommended to do so.
In case you’re confused, let’s clarify it now:
Within Eclipse, we talk about Plug-ins, but we mean Bundles.
Bundle is the generic term. In the context of pure OSGi.
A Plug-in is a Bundle.
A special kind of bundle.
A Plugin is a bundle, and even a bit more, because it contains the specifics of Eclipse.
I hope that this document has clarified some doubts and has encouraged you to move around in the world of OSGi.
As for me, I feel more self-confident about a topic when I’ve touched it with my hands.
Therefore, I’ve created 2 exercises which are easy to follow and will enable you to deal with OSGi based artifacts.
Exercise 1 will demonstrate how to create a bundle, install it and do some operations on the OSGi console.
Exercise 2 will then show how to create a feature and an update site.