Free tutorials for Java, Eclipse and Web programming



Follow me on twitter

OSGi with Eclipse Equinox - Tutorial

Lars Vogel

Version 1.8

20.05.2010

Revision History
Revision 0.103.09.2007Lars Vogel
Created
Revision 0.225.10.2008Lars Vogel
Extended Article
Revision 0.326.11.2008Lars Vogel
Add chapter about creation and consumption of services
Revision 0.427.11.2008Lars Vogel
Added service tracker
Revision 0.4.127.11.2008Lars Vogel
Fixed service tracker
Revision 0.516.02.2009Lars Vogel
Improved OSGi bundle description, added MANIFEST.MF example
Revision 0.625.03.2009Lars Vogel
Added missing source code for QuoteService.java.
Revision 0.727.03.2009Lars Vogel
Added declarative services for OSGi
Revision 0.829.04.2009Lars Vogel
Removed RCP example
Revision 0.914.06.2009Lars Vogel
More detailed on declarative services
Revision 1.015.06.2009Lars Vogel
Live Cycle of services
Revision 1.124.11.2009Lars Vogel
Fixed typos
Revision 1.201.12.2009Lars Vogel
Fixed typo in class name
Revision 1.321.12.2009Lars Vogel
Re-worked the article
Revision 1.422.12.2009Lars Vogel
Improved declarative service description
Revision 1.525.12.2009Lars Vogel
Declarative Service consumer
Revision 1.618.01.2010Lars Vogel
Fixed package names (thanks for Stefan Burger for the feedback)
Revision 1.707.04.2010Lars Vogel
Improved DS chapter, fixed code in DS
Revision 1.820.05.2010Lars Vogel
Bundle-RequiredExecutionEnvironment explained

OSGi with Eclipse Equinox

This tutorial gives an overview of OSGi. It explains the creation and consumption of OSGi services via ServiceTrackers and declarative services. Eclipse Equinox is used as an standalone OSGi server.

For this tutorial Eclipse 3.5 (Galileo) is used.


Table of Contents

1. OSGi
1.1. Overview
1.2. Key features
1.3. Implementations
1.4. OSGi bundles
1.5. Bundle dependencies and public API
1.6. OSGi services
1.7. OSGi dependency management
1.8. Bundle Life cycle
1.9. OSGi MANIFEST.MF example
2. Installation
3. OSGI console
4. Your first OSGi bundle
4.1. Create
4.2. Coding
4.3. Run
4.4. Export your bundle
5. Running a standalone OSGI server
6. Define a Service and service consumption
6.1. Overview
6.2. How to build services
6.3. Define the service interface
6.4. Create service
6.5. Install service bundles
6.6. Use your service
6.7. Use your service with a service tracker
6.8. Problems with service tracker
7. Declarative Services
7.1. Overview
7.2. Define a declarative service
7.3. Review the result
7.4. Run declarative services
8. Using services via declarative services
9. Thank you
10. Questions and Discussion
11. Links and Literature
11.1. Source Code
11.2. OSGi Resources
11.3. vogella Resources

1. OSGi

1.1. Overview

OSGi is a specification of a service and module platform in Java at runtime. The OSGi specification has several parts, the core of the OSGi specification defines a component and service model. This component model allows to activate, de-activate, update and de-install existing components and services and to install new components / services dynamically.

The smallest unit of modularization in OSGi is a bundle. OSGi defines a registry which bundles can use to publish services or register to other services.

1.2. Key features

The key features of OSGi can get summarized as:

  • Modularization

  • Runtime Dynamic

  • Service Orientation

In the authors personal opinion the strongest feature of OSGi is that you can define which package of your Java Projects should be visible to other Java projects. This way you can effectively control which Java classes in these projects can be used, e.g. define your API.

1.3. Implementations

OSGi has several implementations, for example Knopflerfish OSGi or Apache Felix. Eclipse Equinox is currently the reference implementation of the OSGi specification.

Eclipse Equinox is the runtime environment on which the Eclipse IDE and Eclipse RCP application are based. In Eclipse the smallest unit of modularization is a plugin. The terms plugin and bundle are (almost) interchangable. An Eclipse plugin is also an OSGi bundle and vice versa.

Tip

Eclipse extends the concept of bundles with extension points .

1.4. OSGi bundles

The OSGi specification defines the OSGi bundle as the unit of modularization. A bundle is a cohesive, self-contained unit, which explicitly define its dependencies to other modules / services and explicitly defines its external API.

OSGi bundles are .jar files with additional meta information. This meta information is stored in the folder "META-INF" in the file "MANIFEST.MF". MANIFEST.MF is part of a standard jar specification. Any non-OSGI runtime will ignore the OSGI metadata. Therefore OSGi bundles can be used without restriction in non-OSGi Java environments.

Each bundle has a symbolic name which is defined via the property "Bundle-SymbolicName" in the MANIFEST.MF. Convention is that this name starts with the reverse domain name of the author of the bundle, e.g. "de.vogella.myfirstbundle".

Each bundle has also a version number in the property "Bundle-Version". This version number and the symbolic name uniquely identify a bundle in OSGi. The OSGi runtime can load the same bundle with different version numbers.

1.5. Bundle dependencies and public API

Via MANIFEST.MF a bundle can define its dependency to other bundles and services. A bundle can define that it depends on a certain version (or a range) of another bundle, e.g. bundle A can define that it depends on bundle C in version 2.0, while bundle B defines that it depends on version 1.0 of bundle C.

If a class wants to use a class from another bundles this dependency must be defined in the MANIFEST.MF, otherwise you will receive a ClassNotFound Exception. This restriction is enforced via a specific OSGi classloader.

MANIFEST.MF also defines the Java classes which should be available to other bundles as public API. This definition is done based on the packages name. Classes which are not exported via the MANIFEST.MF are not visible to other bundles. This restriction is enforced in OSGi via a special Java class loader. Access to the restricted classes is not possible, also not via reflection.

1.6. OSGi services

A bundles can register and use services in OSGi. OSGi provides therefore a central registry for this purpose. A service is defined by a Java interface (POJI - plain old Java interface).

Access to the service registry is performed via the class BundleContext. OSGi injects the BundleContext into each bundle during the startup of the bundle. A bundle can also register itself to the BundleContext ServiceEvents which are for example triggered if a new service is installed or de-installed.

1.7. OSGi dependency management

OSGi is responsible for the dependency management between the bundles. These dependencies can be divided into:

  • Bundle (Package) Dependencies

  • Service Dependencies

OSGi reads the manifest.mf of a bundle during the installation of the plugin and ensures that all dependent bundles are also loaded if the bundle is activated. If the dependencies are not meet then the bundle is not loaded. Bundle / package dependencies are based on dependencies between standard Java objects and in case OSGi can not resolve all dependencies this results in a ClassNotFoundException.

As service in OSGi can be dynamically started and stopped, therefore the bundles must manage these dependencies themselves. The bundles can use the service listeners to get informed if a services is stared or stopped.

1.8. Bundle Life cycle

With the installation of a bundle in the OSGi runtime this bundle is persisted in a local bundle cache. The OSGi runtime is then trying to resolve all dependencies of the bundle. If all required dependencies are resolved the bundle is in the status "RESOLVED" otherwise it is in the status "INSTALLED". If several bundles exists which would satisfy the dependency then the bundle with the highest version is taking. If the version are the same then the bundle with the lowest ID is taken. If the bundle is started its status is "STARTING". Afterwards it is "ACTIVE".

1.9. OSGi MANIFEST.MF example

The following is an example of a MANIFEST.MF.

				
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Popup Plug-in
Bundle-SymbolicName: de.vogella.rcp.intro.commands.popup; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: de.vogella.rcp.intro.commands.popup.Activator
Require-Bundle: org.eclipse.ui,
 org.eclipse.core.runtime
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6

			

Tip

Via the "Bundle-RequiredExecutionEnvironment" statement a bundle can specify which Java version is required to run the bundle. If this requirement is not fulfilled then the OSGi runtime does not load the bundle.