OSGi goes Enterprise

Putting it together

Eclipse Gemini JPA [5] liefert eine Implementierung des OSGi Services für JPA. Dessen Verhalten ist genau wie oben beschrieben. Um die Gemini-JPA-Implementierung zu verwenden, müssen wir lediglich das OSGi Bundle org.eclipse.genimi.jpa_1.0.0.RELEASE.jar in unserem OSGi-Container deployen. Schauen wir uns das nun an einem Beispiel an. Das Beispielprojekt finden Sie bei Github [10]. Das Beispiel enthält die komplette Enterprise-Anwendung mit Eclipse Gemini und wird uns über die gesamte Artikelserie begleiten. Unser Beispielprojekt hat eine Persistence Unit mit dem Namen Accounts. Diese Persistence Unit enthält die beiden JPA-Entitäten Account und Customer. Als Datenbank nehmen wir H2, und Eclipse Link als JPA-Implementierung.

Bevor es ans Eingemachte geht, aber noch ein letzter Schlenker. Unsere Enterprise-Anwendung soll nicht ausschließlich mit JPA arbeiten können, sondern in der Lage sein, zukünftig auch andere Mechanismen zu nutzen. Daher verwenden wir Interfaces für die Domain-Objekte der Enterprise-Anwendung. Die Businesslogik arbeitet dann ausschließlich auf diesen Interfaces. Mit JPA stellen wir eine Implementierung dieser Interfaces bereit. In unserer Anwendung haben wir also bis jetzt ein Bundle mit den Interfaces der Domain-Objekte und ein Bundle mit der Persistence Unit Accounts. Das Beispielprojekt enthält für jedes OSGi Bundle ein Eclipse-Projekt. Das Projekt mit den Interfaces der Domain-Objekte heißt com.pe-international.sample.model.api, das mit der Persistence Unit com.pe-international.sample.model.jpa. Das Bundle mit der Persistence Unit schauen wir uns nun näher an.

Das Eclipse-Projekt com.pe-international.sample.model.jpa enthält zwei gewöhnliche JPA-Entitäten AccountImpl und CustomerImpl, die die Interfaces unserer Domain-Objekte Account und Customer implementieren. Im Verzeichnis META-INF liegt die Datei mit den Mapping-Metadaten für JPA persistence.xml. Dort sind alle JPA-Entitäten aufgeführt. Datenbanktreiber und JDBC Connection String sowie weitere Konfiguationseinstellungen werden hier ebenfalls angegeben. Auch diese Datei sieht aus wie gewohnt. Spannend ist nun der Inhalt der OSGi-Manifestdatei MANIFEST.MF, der in Listing 2 aufgeführt ist.

Listing 2
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Meta-Persistence: META-INF/persistence.xml
Bundle-Name: PE Jpa Model
Bundle-SymbolicName: com.pe-international.sample.model.jpa
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: PE-INTERNATIONAL
Import-Package: javax.persistence;jpa="2.0";version="1.1.0",
 javax.persistence.criteria;jpa="2.0";version="1.1.0",
 javax.persistence.metamodel;jpa="2.0";version="1.1.0",
 model.account,
 org.osgi.framework;version="1.6.0",
 org.osgi.service.jpa,
 org.osgi.util.tracker
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-Activator: sample.Activator
Export-Package: model.account.jpa

In der dritten Zeile ist unter dem Eintrag Meta-Persistence die Konfigurationsdatei der Persistence Unit angegeben, in unserem Fall also META-INF/persistence.xml. Diese Zeile sorgt dafür, dass Gemini JPA erkennt, dass unser Bundle eine JPA Persistence Unit enthält. Das heißt, Gemini JPA liest automatisch die Datei persistence.xml ein und stellt einen OSGi Service EntityManagerFactory mit der Service Property osgi.unit.name=Accounts bereit. Damit dies funktioniert, muss das Bundle natürlich auch das Package mit den JPA-Entitäten nach außen freigeben, sprich exportieren. In den Abhängigkeiten des Manifests steht Eclipse Link und der JPA-Service der Enterprise-Spezifikation org.osgi.service.jpa. Aber wo steht der Datenbanktreiber? Im Manifest ist keiner zu finden! Also wie können wir dann die JPA-Entitäten in einer H2-Datenbank speichern?

Hier kommt nun die im ersten Abschnitt beschriebene Integration von JDBC und OSGi ins Spiel, und somit Gemini DBAccess. Gemini JPA verwendet nämlich den JDBC-Service der OSGi-Enterprise-Spezifikation, genauer gesagt, die Implementierung Gemini DBAccess. Erzeugt Gemini JPA eine EntityManagerFactory für eine Persistence Unit, so nutzt es den JDBC-Service, um an den JDBC-Treiber zu kommen. Für unser Beispielprojekt heißt dies, dass das Bundle mit der Persistence Unit keine Abhängigkeit zu einem konkreten Datenbanktreiber enthält. Zur Compile-Zeit benötigen wir nur das API der OSGi-Enterprise-Spezifikation. Zur Laufzeit muss eine Implementierung der JDCB und JPA-Enterprise-Services zur Verfügung stehen, in unserem Fall durch Gemini DBAccess und Gemini JPA. Prinzipiell wären wir also auch in der Lage, jederzeit eine andere Implementierung der Enterprise-Spezifikation zu verwenden, wie beispielsweise Apache Aries [11].

Kommentare

Schreibe einen Kommentar

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