O'Reilly logo

Die OSGi Service Platform: Eine Einführung mit Eclipse Equinox by Matthias Lübken, Bernd Kolb, Nils Hartmann, Gerd Wütherich

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

93
6 OSGi Services
Motivation
Wenn Sie bereits Erfahrung in der Entwicklung von Eclipse-Plug-ins
oder Plug-in-basierten Anwendungen auf Basis der Eclipse Rich Client
Platform (RCP) besitzen, dann wird Ihnen vieles, was Sie in den ver-
gangenen Kapiteln gelernt haben, in der ein oder anderen Form
bekannt sein. Ein für Eclipse-Plug-in- bzw. RCP-Entwickler eher unbe-
kanntes Konzept sind hingegen die OSGi Services, die wir Ihnen in die-
sem und dem nachfolgenden Kapitel vorstellen.
OSGi Services sind einfache Java-Objekte (POJOs), die innerhalb
eines Bundles erzeugt und an der zentralen OSGi Service Registry regis-
triert werden. Dort können sie von anderen Bundles abgefragt und
genutzt werden. Durch die Verwendung von OSGi Services ist es damit
möglich, Objekte über Bundle-Grenzen hinweg verfügbar zu machen.
Wir werden Ihnen in diesem Kapitel detailliert zeigen, wie Sie Ser-
vices an der OSGi Service Registry anmelden und abfragen. Darüber
hinaus erläutern wir Ihnen die Verwendung von Properties und Filtern,
mit denen Sie Services beschreiben und detailliert suchen können. Wir
erklären den Zusammenhang zwischen Package- und Service-Abhän-
gigkeiten und stellen Ihnen abschließend die Verwendung von Start-
Leveln vor.
Einordnung
Die in diesem Abschnitt beschriebenen Konzepte sind logisch im
Service-Layer des OSGi Frameworks angesiedelt.
Die Spezifikation der vorgestellten Konzepte können Sie in Kapitel 5
der OSGi Core Specification [OSCS07] nachlesen.
Abb. 6–1
Einordnung in die
logischen Framework-
Schichten
OSGi Framework
Specification
Module-Schicht
Lifecycle-Management-Schicht
Service-Schicht
Secu-
rity
Framework
Services
6 OSGi Services94
6.1 Tutorial: Der Translation Service als OSGi Service
Überblick
Wir werden in diesem Kapitel das bestehende Beispiel dahingehend
umbauen, dass der Translation Service nicht mehr über eine Factory
erzeugt, sondern als OSGi Service über die Service Registry zur Verfü-
gung gestellt wird. Das »Hello World«-Bundle kann den Translation
Service dann von der Service Registry abfragen und nutzen (vgl. Abb.
6–2).
Die
TranslationServiceFactory, die wir im Beispiel des vorherigen
Unterkapitels implementiert haben, wird damit überflüssig. Stattdes-
sen erweitern wir das »Translation«-Bundle um einen Bundle-Aktiva-
tor, der beim Start des Bundles einen Translation Service erzeugt und
an der Service Registry anmeldet.
Die Plug-in-Projekte
In Abb. 6–3 ist der Aufbau der fertigen Plug-in-Projekte darge-
stellt.
Abb. 6–2
Der Translation Service
MANIFEST.MF
META-INF
org.osgibook.helloworld
verwendet
Klassen aus
META-INF
MANIFEST.MF
org.osgibook.translation.impl
org.osgibook.translation
TranslationService
verwendet Service
Abb. 6–3
Aufbau der
Plug-in-Projekte
956.1 Tutorial: Der Translation Service als OSGi Service
Schritt 1: Den Translation Service als OSGi Service anmelden
Da das »Translation«-Bundle noch keinen Activator besitzt, ssen
Sie diesen zunächst neu anlegen. Melden Sie dazu den
Activator im
Bundle Manifest mit folgendem Eintrag an:
Bundle-Activator: org.osgibook.translation.impl.Activator
Anschließend erzeugen Sie die Klasse Activator im Package org.osgi.
translation.impl
. Das Listing 6–1 zeigt die Implementierung der Acti-
vator
-Klasse. In der start()-Methode des Activators wird der Trans-
lation Service über die Methode
BundleContext.registerService() an der
Service Registry registriert. Eine explizite Deregistrierung des Service
muss nicht erfolgen, da das OSGi Framework beim Beenden eines
Bundles automatisch alle vom Bundle registrierten Services aus der
Service Registry entfernt:
package org.osgibook.translation.impl;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Locale;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgibook.translation.TranslationService;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
Locale locale = Locale.getDefault();
Dictionary<String, String> properties =
new Hashtable<String, String>();
properties.put(Locale.class.getName(), locale.toString());
context.registerService(
TranslationService.class.getName(),
new TranslationServiceImpl(locale), properties);
}
public void stop(BundleContext context) throws Exception {
// Deregistrierung erfolgt automatisch
}
}
Löschen Sie nun noch die Klasse TranslationServiceFactory. Nach dem
Entfernen der Factory treten zunächst einige Kompilierfehler im
»Hello World«-Bundle auf, die wir jedoch im nächsten Schritt beheben
werden.
Listing 6–1
Der Activator des
Translation-Bundles
6 OSGi Services96
Schritt 2: Verwenden des OSGi Service im »Hello World«-Bundle
Der Translation Service wird wie bisher in der Klasse Activator des
»Hello World«-Bundles benutzt. Allerdings müssen Sie den Code zum
Auffinden des Service so anpassen, dass der in Schritt 1 angemeldete
Service von der OSGi Service Registry abgefragt wird. Das machen wir
in einer modifizierten Version der
greet()-Methode. Das folgende Lis-
ting 6–2 zeigt den fertigen Activator:
package org.osgibook.helloworld;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgibook.translation.TranslationService;
public class Activator implements BundleActivator {
private BundleContext bundleContext;
public void start(BundleContext context) throws Exception {
this.bundleContext = context;
greet("hello", context.getBundle().getSymbolicName());
}
public void stop(BundleContext context) throws Exception {
greet("goodbye", context.getBundle().getSymbolicName());
}
protected void greet(String key, Object... args) {
ServiceReference serviceReference = bundleContext
.getServiceReference(TranslationService.class.getName());
if (serviceReference != null) {
TranslationService translationService =
(TranslationService) bundleContext
.getService(serviceReference);
if (translationService != null) {
String translatedMsg =
translationService.getTranslation(key);
String message = String.format(translatedMsg, args);
System.out.println(message);
}
bundleContext.ungetService(serviceReference);
}
} else {
System.out.println(
"TranslationService z.Zt. nicht verfuegbar.");
}
}
Listing 6–2
Der Aktivator des
»
Hello World
«
-Bundles
976.1 Tutorial: Der Translation Service als OSGi Service
Schritt 3: Festlegen der Bundle-Startreihenfolge
Bevor Sie das Beispiel ausführen können, müssen Sie noch eine Anpas-
sung in der »Hello World«-Launch-Konfiguration vornehmen: Da das
Bundle
org.osgibook.helloworld seinen Gruß nur dann ausgeben kann,
wenn der Translation Service als OSGi Service angemeldet ist, müssen
Sie dafür sorgen, dass das Bundle
org.osgibook.translation vor dem
Bundle
org.osgibook.helloworld gestartet wird.
Die relative Startreihenfolge lässt sich innerhalb des OSGi Frame-
work durch die Verwendung von Start-Leveln realisieren, die jedem
einzelnen Bundle zugewiesen werden können. Weisen Sie deshalb in
der Launch-Konfiguration dem Bundle
org.osgibook.translation
einen niedrigeren Start-Level zu als dem Bundle org.osgibook.hello-
world
(vgl. Abb. 6–4).
Die Verwendung von Start-Leveln zur Auflösung von Service-Abhängigkeiten
wird in der OSGi-Spezifikation explizit als Fehler beschrieben, da der poten-
ziellen Dynamik von OSGi-basierten Anwendungen nicht Rechnung getragen
wird.
Da wir jedoch den Umgang mit dynamischen Services aus didaktischen
Gründen erst in Kapitel 7 behandeln, müssen wir in diesem Tutorial die Start-
reihenfolge über Start-Level spezifizieren.
Abb. 6–4
Die Launch-Konfiguration
Achtung

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required