Von Null auf REST mit JAX-RS

Hallo OSGi

Nachdem die Target Platform eingerichtet ist, wird ein erstes OSGi-Bundle-Projekt angelegt. Das Projekt stellt einen OSGi Service zum Erstellen von Grußnachrichten zur Verfügung. Um ein neues Projekt anzulegen, wird der PDE Plug-in Project Wizard genutzt. Dieser ist über FILE | NEW | PROJECT. | PLUG-IN DEVELOPMENT | PLUG-IN PROJECT erreichbar. Der Wizard erstellt ein neues Projekt im Workspace inklusive dem Basis-Rumpf für ein OSGi Bundle oder ein Eclipse Plug-in. Durch die Auswahl des Radio Buttons „an OSGi framework“ wird festgelegt, dass es sich um ein OSGi Bundle handelt. Der Unterschied zu einem Eclipse Plug-in ist das Fehlen der plugin.xml und das Ausblenden der Reiter EXTENSIONS und EXTENSION POINTS im PDE Manifest Editor.

Nach Eingabe des Projektnamens auf der ersten Seite des Wizards (Abb. 2) gelangt man mit NEXT auf die nächste Seite (Abb. 3). Dort können die Standardvorgaben akzeptiert werden. Lediglich das Häkchen bei „Generate an activator“ sollte entfernt werden, da im Beispiel der Service als OSGi Declarative Service (DS) bereitgestellt werden soll, was keinen Activator-Code erfordert. Der Wizard wird mit einem Klick auf FINISH beendet. Nachdem das Projekt im Workspace angelegt wurde, wird der Service wie in Listing 1 skizziert angelegt.

Abb. 3: New Plug-in Project Wizard – Seite 2
Listing 1: Service Interface und Implementierung für Grußbotschaften
public interface GreetingService {
  /** Returns a list of all available greetings. */
  Collection getGreetings() throws Exception;
  /** Adds a new greeting. */
  void sayHello(final String greeting) throws Exception;
}
// * Implementation of {@link GreetingService} 
public class GreetingServiceImpl implements GreetingService {
  List greetings = new CopyOnWriteArrayList();
  public Collection getGreetings() throws Exception {
    return Collections.unmodifiableList(greetings);
  }
  public void sayHello(final String greeting) throws Exception {
    greetings.add(greeting);
  }
}

Um den Service mittels OSGi Declarative Services anderen Bundles zur Verfügung zu stellen, muss eine OSGi-DS-Komponente erstellt werden. Sie besteht aus einer XML-Datei (Component Definition) und einer Java-Klasse (Component Class). Weiterhin muss die XML-Datei im Bundle Manifest (META-INF/MANIFEST.MF) durch einen Service-Component-Eintrag referenziert sein. Eine OSGi-DS-Komponente kann Abhängigkeiten zu anderen OSGi Services deklarieren und selbst OSGi Services bereitstellen. Erst wenn alle erforderlichen Abhängigkeiten aufgelöst sind, wird die Komponente im System bereitgestellt. Im Beispiel sind keine Abhängigkeiten vorhanden sondern es wird nur ein Services bereitgestellt. Dazu muss die Java-Klasse der Komponente das Interface implementieren. Weiterhin muss die Klasse der Komponente einen Konstruktor ohne Argument besitzen. Im Beispiel kann die GreetingServiceImpl-Klasse direkt als Klasse der Komponente genutzt werden. Allerdings wird in der Praxis dieses direkte Pattern nicht immer empfohlen. Gerade wenn man die eigentliche Implementierung des Services frei von OSGi-Abhängigkeiten halten möchte empfiehlt sich eine eigene Klasse für die Komponente, die an die eigentliche Implementierung delegiert. In Listing 2 ist dieses Pattern abgebildet.

Eine OSGi-DS-Komponente kann bequem über einen Wizard in Eclipse erstellt werden. Der Wizard wird über FILE | NEW | OTHER. | PLUG-IN DEVELOPMENT | COMPONENT DEFINITION gestartet. Nach Eingabe von Dateinamen, Namen und Klasse der Komponente erstellt der Wizard die Component-Definition-XML-Datei samt Grundgerüst und fügt auch den notwendigen Eintrag in der MANIFEST.MF hinzu. Es empfiehlt sich, alle Component Definitions in einem Ordner namens OSGI-INF abzulegen. Dadurch ist einerseits schnell erkennbar, dass es sich bei den XML-Dateien um OSGi-DS-Komponenten handelt, andererseits muss so nur der gesamte Ordner in der build.properties referenziert werden und nicht jede Datei einzeln. Der Wizard erledigt zwar auch das, gerade aber bei manueller Erstellung wird das oft übersehen und dann fehlen die Komponenten-XML-Dateien im exportierten/gebauten Bundle. Das fertige Projekt ist in Abbildung 4 zu sehen und kann auch online abgerufen werden [5].

Abb. 4: Hallo-OSGi-Beispielprojekt
Listing 2: OSGi-DS-Komponente
OSGI-INF/greeting-service.xml:


GreetingServiceComponent.java:
public class GreetingServiceComponent implements GreetingService {
  private GreetingService service;
  public void activate(final ComponentContext context) {
    // create real service when activating component
    service = new GreetingServiceImpl();
  }
  public void deactivate(final ComponentContext context) {
    service = null; // dispose real service
  }
  @Override
  public Collection getGreetings() throws Exception {
    return getService().getGreetings();
  }
  public GreetingService getService() {
    final GreetingService greetingService = service;
    if (greetingService == null)
      throw new IllegalStateException("inactive");
    return greetingService;
  }
  @Override
  public void sayHello(final String greeting) throws Exception {
    getService().sayHello(greeting);
  }
}

META-INF/MANIFEST.MF:
Manifest-Version: 1.0
Bundle-SymbolicName: hello.service
...
Service-Component: OSGI-INF/greeting-service.xml
Bundle-ActivationPolicy: lazy

build.properties:
bin.includes = META-INF/,
               .,
               OSGI-INF/
...
Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.