2. Agenda
OSGi für Praktiker
Vorstellung
Ablauf des Workshops
Administratives
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
3. OSGi für Praktiker
Praxis Buch
OSGi im Enterprise Umfeld
Build, Run, Manage
Maven basierte Pax Tools
@OSGiBuch
http://www.osgi-buch.com/
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
4. Vorstellung – Bernd Weber
Senior Consultant (Enterprise Backends)
Co-Autor von OSGi für Praktiker
Interessens-Schwerpunkte
– Öffentlicher Bereich
– OpenSource Software
– Infrastruktur-Projekte
– IT-Standards (SAGA, V-Modell XT)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
5. Vorstellung – Oliver Braun
Professor für Programmierung und Verteilte Systeme
Co-Autor von OSGi für Praktiker
Autor von Scala – Objektfunktionale Programmierung
Interessens-Schwerpunkte
– Funktionale Programmierung in Haskell
– Objektfunktionale Programmierung in Scala
– Entwicklung verteilter Systeme
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
6. Vorstellung – Patrick Baumgartner
Senior Software Consultant @ Swiftmind
Co-Autor von OSGi für Praktiker
Initiator des OSGi Users' Forum Switzerland
Architektur, Coaching, Workshops, Trainings,
Reviews & Entwicklung
– Java Web Entwicklung mit Spring
– OSGi mit Spring DM & Spring
– Agile Software Development
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
7. Ablauf des Workshops – 9:30
Begrüssung & Vorstellung 5'
Einführung in OSGi 40'
Projekt Setup 30'
Bundle Playground 15'
Web Console *
Kaffeepause 30'
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
8. Ablauf des Workshops – 11:30
Deklarative Services 40'
Blueprint Services 20'
Mittagspause 60'
Web Bundles 20'
Fragmente & Integrationstests 40'
Kaffepause 30'
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
9. Ablauf des Workshops – 15:30
Distributed OSGi 45'
Outlook Scala Modules 25'
Launcher 15'
Fragen
Ende
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
11. Einleitung
Oliver Braun
Pax
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 1
12. OSGi
JSR 291: „Dynamic Component Support for Java
SE“ (= OSGi-Spezifikation 4.1)
Aktuell 4.2
– Distributed OSGi
– Enterprise Edition
– ...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
13. Die ersten Schritte
1999 Gründung OSGi Alliance
– Open Service Gateway Initiative
(heute nur OSGi)
2000 Release 1
– Fokus: Home Network Gateways
…
2003 Release 3
– Fokus auch auf Automotive & Entertainment
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
14. ... und die nächsten
2004 Eclipse Release 3
2005 Release 4
– Mobile Devices
2009 Release 4.2
2010 Enterprise Edition
– Web Applications
– Distributed OSGi
– JMX
– …
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
15. Bundles
Entspricht einem Modul
JAR + OSGi-Manifest
Manifest-Header
– Bundle-SymbolicName
– Bundle-Version
– Bundle-Name
– ...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
16. Beispiel-Manifest
Bundle-Name: Hello World
Bundle-SymbolicName: biz.gossipmonger.helloworld
Bundle-Description: A hello world bundle
Bundle-ManifestVersion: 2
Bundle-Version: 1.0.0
Export-Package:
biz.gossimonger.helloworld;version=“1.0.0“
Import-Package:
org.osgi.framework;version=“1.3.0“
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
17. Sichtbarkeit
Bei einem JAR ist der gesamte Inhalt sichtbar
Ein OSGi-Bundle exportiert nur explizit
angegebene Packages
Analog muss ein OSGi-Bundle auch explizit
exportieren
Dies geschieht im Manifest:
Export-Package:
biz.gossimonger.helloworld;version=“1.0.0“
Import-Package:
org.osgi.framework;version=“1.3.0“
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
20. BundleActivator
OSGi-Framework → Bundle
public interface BundleActivator {
public void start(BundleContext context)
throws Exception;
public void stop(BundleContext context)
throws Exception;
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
21. BundleContext
Bundle → OSGi-Framework
public interface BundleContext {
…
public Object getService
(ServiceReference ref);
public ServiceRegistration registerService
(String[] clazzes, Object service,
Dictionary properties);
…
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
22. Serviceorientierung
Zusammenarbeit von Bundles über Dienste
Ein Bundle kann n Dienste bereitstellen
Dienst = Java-Objekt
Schnittstelle = Java-Interface
Ein Objekt kann mehrere Dienste bereitstellen
= mehrere Interfaces implementieren
Dienste werden bei der ServiceRegistry
– registriert
– angefragt
Gekapselt in ServiceReference-Objekt
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 12
31. Agenda
Werkzeuge
JobTimer Bundle erstellen
Projekt GossipMonger aufsetzen
GateKeeper Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
32. Werkzeuge – Standard
JDK 1.6.2x
2.2.x oder 3.0
3.6 mit Maven-Plugin m2eclipse
http://m2eclipse.sonatype.org/sites/m2e
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
33. Werkzeuge – OSGi
>= 2.0.x
http://felix.apache.org/site/downloads.cgi
1.26.0
http://www.aqute.biz/Bnd/Download
alias bnd='$JAVA_HOME/bin/java -jar
/path/to/biz.aqute.bnd.jar'
Pax
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
34. Werkzeuge – Pax Construct
Erzeugen und Verwalten von
OSGi-Projekten und Bundles
Archetypen & Shell Skripte, z.B.:
– pax-create-project
– pax-create-bundle
– pax-provision
Herunterladen, auspacken,
bin-Verzeichnis in Suchpfad
http://wiki.ops4j.org/display/paxconstruct/Download
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
35. Werkzeuge – Pax Runner
Zentrales Pax-Werkzeug
Startet die wichtigsten OSGi
Plattformen
Konfiguration über Profile
Kann als Hintergrunddienst
gestartet werden
Herunterladen, auspacken,
bin-Verzeichnis in Suchpfad
http://paxrunner.ops4j.org/display/paxrunner/Download
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
36. Werkzeuge – Pax Exam
Framework für Integrationstests
Basiert auf JUnit und Pax Runner
Konfiguration von Bundles,
Umgebungsparametern,
Plattformen
Verwendung über Maven2-
Dependencies oder Download
http://wiki.ops4j.org/display/paxexam/Download
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
37. Agenda
Werkzeuge
JobTimer Bundle erstellen
Projekt GossipMonger aufsetzen
GateKeeper Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
38. JobTimer – Maven-Struktur
JobTimer ist erstes Bundle
mvn generate:archetype
Vorschlag (Quickstart) übernehmen
Metadaten eingeben:
groupId: biz.gossipmonger
artifactId: jobtimer
version: 0.1.0
package:
biz.gossipmonger.jobtimer
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
39. JobTimer – POM anpassen
pom.xml in Eclipse importieren
File→Import. . . →Maven→Existing Maven Project
Abhängigkeiten zu OSGi-APIs definieren
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>4.2.0</version>
</dependency>
Java-Version definieren
Automatisiertes Testen konfigurieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
40. JobTimer – Bundle erstellen
JobTimer.java in Maven-Struktur einbetten
JAR erstellen (mvn package)
Zum Bundle erweitern mit bnd
– Steuerdatei osgi.bnd erstellen
Bundle-Name: GossipMonger JobTimer
Bundle-SymbolicName: biz.gossipmonger.jobtimer
Bundle-Version: 0.1.0
Bundle-Activator: biz.gossipmonger.jobtimer.JobTimer
Private-Package: biz.gossipmonger.jobtimer
-classpath: target/jobtimer-0.1.0.jar
– Aufruf von bnd osgi.bnd
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
41. JobTimer-Bundle Manifest
Ergebnis: JAR mit erweiterter Manifest-Datei
Bundle-ManifestVersion: 2
Bundle-Name: GossipMonger JobTimer
Bundle-SymbolicName: biz.gossipmonger.jobtimer
Bundle-Version: 0.1.0
Bundle-Activator: biz.gossipmonger.jobtimer.JobTimer
Private-Package: biz.gossipmonger.jobtimer
Import-Package: org.osgi.framework,org.osgi.service.event
,org.osgi.util.tracker
Übrigens: bnd-Steuerdateien sind
– vielseitig durch Variablen, Makros, …
– kaskadierbar
– gut lesbar
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 12
42. bnd-Steuerdatei integrieren
Ziel: Automatisierte Bundle-Erstellung
Werkzeug: maven-bundle-plugin
Verwendet bnd-Steuerdatei
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.1.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>osgi.bnd</_include>
</instructions>
</configuration>
</plugin>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 13
43. JobTimer-POM abrunden
Verpackungsart auf “Bundle” einstellen
<packaging>bundle</packaging>
Hübschen Namen vergeben
<name>GossipMonger JobTimer</name>
Bundle erstellen und in lokalem Maven-
Repository ablegen
mvn install
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 14
44. Agenda
Werkzeuge
JobTimer Bundle erstellen
Projekt GossipMonger aufsetzen
GateKeeper Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 15
45. Gesamtprojekt anlegen
Gesamtprojekt heißt “GossipMonger“
Verwendung von Pax Construct
pax-create-project
Metadaten angeben
groupId: biz.gossipmonger
artifactId: gossipmonger
version: 0.1.0
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 16
46. JobTimer importieren
JobTimer ist Taktgeber für GossipMonger
Autarkes Bundle neben dem Projekt
Import => Definition Abhängigkeit
$ cd gossipmonger
$ pax-import-bundle
groupId: biz.gossipmonger
artifactId: jobtimer
version: 0.1.0
Ergebnis: Erweiterung von provision/pom.xml
<dependencies>
<dependency>
<groupId>biz.gossipmonger</groupId>
<artifactId>jobtimer</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 17
47. Abhängigkeiten-Automatik
JobTimer nutzt u.a. EventAdmin
=> Laufzeit-Abhängigkeit zu API und Impl.
Ziel: beim Plattformstart mitladen
Werkzeuge: maven-pax-plugin, Profile
<plugin>
<groupId>org.ops4j</groupId>
<artifactId>maven-pax-plugin</artifactId>
<version>1.4</version>
<configuration>
<provision>
<param>--platform=felix</param>
<param>--profiles=compendium,event</param>
</provision>
</configuration>
</plugin>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 18
48. Agenda
Werkzeuge
JobTimer Bundle erstellen
Projekt GossipMonger aufsetzen
GateKeeper Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 19
49. GateKeeper Bundle
GateKeeper-Bundle ist erstes Projekt-Modul
Ziel: Unmittelbare GossipMonger-Integration
Werkzeug: pax-create-bundle (Pax Construct)
$ cd gossipmonger
$ pax-create-bundle
package: biz.gossipmonger.gatekeeper
bundleName: biz.gossipmonger.gatekeeper
bundleGroupId: biz.gossipmonger
version: 0.1.0
<modules>
<module>poms</module>
<module>provision</module>
<module>biz.gossipmonger.gatekeeper
</module>
</modules>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 20
50. POM Zuständigkeiten
pom.xml
Master-POM, allg. Definitionen, Module (Bundles)
biz.gossipmonger.gatekeeper/pom.xml
Bundle-Daten
poms/pom.xml
globale Abhängigkeiten (u.a. OSGi API) und
Verweise auf die nachfolgenden POMs
poms/compiled/pom.xml
vordefinierte OSGi-Header, Einbindung osgi.bnd
poms/wrappers/pom.xml
OSGi-Wrapper für Drittbibliotheken
provision/pom.xml
spezifische Abhängigkeiten -> JobTimer
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 21
51. GateKeeper Metadaten
Viele Default-Werte passen bereits
Nachziehen von Activator, Sichtbarkeit (, Name)
Werkzeug: Erweiterung von osgi.bnd (, POM)
Bundle-Activator: ${bundle.namespace}.GateKeeper
Private-Package: ${bundle.namespace}
Export-Package:
Import-Package: *
Überschreibt Standardwerte von Pax Construct
GateKeeper ist nun startklar und “unsichtbar“
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 22
53. Apache Felix - Installation
Apache Felix Framework Distribution 3.0.7
herunterladen (http://felix.apache.org/site/downloads.cgi)
Entpacken
Ins Verzeichnis felix-framework-3.0.7 wechseln
Apache Felix Framework starten
java -jar bin/felix.jar
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
54. Apache Felix – Befehle (1)
Mögliche Befehle auf der Konsole abrfagen
g!help
Apache Felix Befehle
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
55. Apache Felix – Befehle (2)
Apache Gogo Befehle
OBR Befehle
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
56. Apache Felix - Status
Installierte Bundles und deren Status auf der Gogo
Konsole abfragen
g!lb
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
57. JobTimer installieren
g!install file:/pathtofile/jobtimer.jar
g!lb
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
58. JobTimer starten
g!resolve 4
g!start 4
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
59. JobTimer deinstallieren
g!stop 4
g!start 4
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
60. Apache Felix – Befehle (2)
Apache Gogo Befehle
OBR Befehle
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
61. Apache Felix - Status
Installierte Bundles und deren Status auf der Gogo
Konsole abfragen
g!lb
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
62. Pax-Runner - Apache Felix
Apache Felix mit Pax-Runner starten
$pax-run
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
63. Pax-Runner - Profile
Pax-Runner mit bereits vorbereiteten Profilen starten
http://paxrunner.ops4j.org/space/Pax+Runner+profiles+list
https://scm.ops4j.org/repos/ops4j/projects/pax/runner-
repository/org/ops4j/pax/runner/profiles/
$pax-run --profiles=log
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 12
64. Pax-Runner - Plattformen
Pax-Runner mit Apache Felix, Equinox, Knopflerfish
starten
$pax-run --platform=equinox
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 13
65. Bundles mit URL installieren
osgi>install http://www.osgi-
buch.com/tutorial/jobtimer.jar
Status mit osgi>ss prüfen
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 14
67. Apache Felix Web Console
Weitere Informationen abrufbar unter
http://felix.apache.org/site/apache-felix-web-console.html
$pax-run –-profiles=web,jsp,felix.webconsole
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
68. Web Console
URL: http://localhost:8080/system/console
Benutzername/Passwort: admin/admin
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
69. Web Console - Bundles
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
70. Web Console - Shell
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
71. Web Console – Config (1)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
72. Web Console – Config (2)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
73. Security
Konsole unterstützt momentan sehr wenig Security:
– Authentifizierung per HTTP Basic
– Kein SSL
– Standard User/Passwort
Für den sicheren Einsatz in Produktion muss
noch einiges getan werden!
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
75. Agenda
Überblick
Enunciator Bundle integrieren
Worker Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
76. Überblick
OSGi APIs: mächtig, Verwendung teils schwierig
API-Verwendung => Starke Kopplung
=> Widerspruch zu OSGi-Prinzipien
=> Maximale Forderung: POJOs ohne API-Bezug
Optimum: Deklaration von Verhalten/Bezügen
Verschiedene deklarative Ansätze
– Apache iPOJO
– OSGi Declarative Services
– OSGi Blueprint Container (Spring-DM)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
77. Declarative Services Spec.
Teil des OSGi Standards
Ausgereifte Technologie
Konfiguration einzelner Komponenten per XML
Verweis in Bundle-Header Service-Component
z.B. Service-Component: OSGI-INF/worker.xml
BundleActivator wird nicht benötigt
Friedliches Nebeneinander von
– Declarative Services (DS),
– Blueprint Service Container und
– Direkter API-Verwendung (BundleActivator
u.a.)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
78. Declarative Services Spec.
Komponenten-Deklaration in XML, u.a.
– Komponenten-Name
– Implementierungsklasse
– Deklarieren angebotener Dienste (Interface)
– Deklarieren referenzierter Dienste, jeweils
• Interface
• Kardinalitäten (optional)
• bind / unbind-Methoden (optional)
– Laufzeitverhalten: statisch oder dynamisch
– Konfigurationsdaten, ...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
79. Laufzeitumgebung (SCR)
DS-Bundles benötigen Laufzeitumgebung
(Service Component Runtime, SCR)
– Initialisieren
– Herstellen / Aktualisieren von Referenzen
– Aktivieren / Deaktivieren
SCR ist ein Bundle – was sonst :-)
Manuelle Installation z.B. mittels
install http://archive.apache.org/dist/felix/
org.apache.felix.scr-1.0.8.jar
Verwendung Pax Runner Profil
– Ergänzen von gossipmonger/pom.xml um
<param>--profiles=[...],ds</param>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
80. Agenda
Überblick
Enunciator Bundle integrieren
Worker Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
82. Enunciator Bundle
Neues Teilprojekt im gossipmonger-Verzeichnis
$ pax-create-bundle
package: biz.gossipmonger.enunciator
bundleName: biz.gossipmonger.enunciator
bundleGroupId: biz.gossipmonger
version: 0.1.0
In Eclipse importieren, Beispiel-Dateien löschen
Schnittstellen-Datei Enunciator.java erstellen in
src/main/java/biz/gossipmonger/enunciator
public interface EnunciatorService {
void enunciate(String text);
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
83. Enunciator Bundle
EnunciatorServiceImpl erstellen
– Package biz.gossipmonger.enunciator.internal
– Entspricht Pax-Hierarchie der Bundle-Packages
Implementiert die Schnittstelle EnunciatorService
Enthält optionale de-/activate-Methoden (DS)
Nutzt dynamisch auftretende LogServices
– Kein LogService vorhanden => Konsole
Ggf. Master-POM um Compiler-Einstellung >=
Java 1.5 ergänzen
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
84. Enunciator
public class EnunciatorServiceImpl implements EnunciatorService {
List<LogService> logServices = new ArrayList<LogService>();
public void addLogService(LogService ls) {
logServices.add(ls);
enunciate("Enunciator got a LogService. Now there are " +
logServices.size() + " references.");
}
public void removeLogService(LogService ls) {
logServices.remove(ls);
enunciate("Enunciator lost a LogService. Now there are " +
logServices.size() + " references.");
}
// further methods -> next slide
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
85. Enunciator (2)
...
public void enunciate(String text) {
if (logServices.size() > 0) {
for (LogService ls : logServices) {
ls.log(LogService.LOG_INFO, text);
}
} else {
System.out.println("Enunciator has no LogService; Message is: "
+ text);
}
protected void activate(ComponentContext cc) {
System.out.println("Enunciator activated.");
}
protected void deactivate(ComponentContext cc) {
System.out.println("Enunciator deactivated.");
}
...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 12
86. Dienst deklarieren
Neues Verzeichnis src/main/resources/OSGI-INF
Darin Datei EnunciatorServiceImpl.xml anlegen
Schema: http://www.osgi.org/xmlns/scr/v1.0.0
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 13
87. Deklaration bekanntgeben
biz.gossipmonger.enunciator/osgi.bnd
BundleActivator-Zeile löschen
Neue (einzige) Zeile für Service-Component
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 14
89. Test der Bundles
Wechsel in gossipmonger-Verzeichnis
Aufruf von pax-provision
Ergebnis:
Welcome to Felix
================
-> Bundle is starting...
Bundle has started.
Enunciator activated.
Enunciator has no LogService; Message is: GateKeeper
created watched directory [...]/runner/render_input
org.osgi.service.event.Event [topic=biz/gossipmonger/jobtimer]
[FelixStartLevel] INFO biz.gossipmonger.enunciator -
Enunciator got a LogService. Now there are 1 references.
org.osgi.service.event.Event [topic=biz/gossipmonger/jobtimer]
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 16
90. Agenda
Überblick
Enunciator Bundle integrieren
Worker Bundle integrieren
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 17
92. Worker Service Bundles
Worker-Zweck: XML in Ausgabeformat rendern
Je ein Bundle für API und Implementierung
Beide: package biz.gossipmonger.worker
bundleName biz.gossipmonger.worker-api / -impl
-api in biz/gossipmonger/worker
-impl in biz/gossipmonger/worker/internal
Worker-Service deklarativ anmelden
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 19
93. Worker API
POM: nur Metadaten, gener. Properties und Name
Private-/Export-Package in osgi.bnd anpassen
(Warnungen wegen gelöschtem internal-Verzeichnis)
Service: Schnittstelle für XML-In und File-Out
public interface WorkerService {
File process(File file);
File process(File file, String outputDir);
File process(InputStream is, String inputFilename);
File process(InputStream is, String inputFilename,
String outputDir);
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 20
94. Worker Implementierung
public final class WorkerServiceImpl implements WorkerService {
...
protected void activate(ComponentContext context) {
enunciate("activating...");
configuredOutput = getConfiguredOutput(context);
enunciate("activated.");
}
protected void deactivate(ComponentContext context) {
enunciate("deactivated.");
}
public void setEnunciatorService(EnunciatorService es) {
if (es != null) {
enunciator = es;
enunciate("EnunciatorService set.");
} else {
enunciate("setEnunciatorService called with null argument.");
}
}
public void unsetEnunciatorService(EnunciatorService es) {
enunciate("EnunciatorService unset.");
enunciator = null;
}
...
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 21
95. Worker Implementierung (2)
public File process(File file) {
return process(file, configuredOutput);
}
public File process(File file, String outputDir) {
enunciate("Render from "+file.getAbsolutePath());
try {
return process(new FileInputStream(file), file.getName(), outputDir);
} catch (FileNotFoundException e) {
enunciate(file.getAbsolutePath() + " is not there!");
return null;
}
}
...
public File process(InputStream is, String inputFilename, String outputDir) {
enunciate("Rendering...");
try {
File output = renderer.render(is, inputFilename, outputDir);
enunciate("Rendered to "+output.getAbsolutePath());
return output;
} catch (Exception ex) {
enunciate("Error while rendering: "+ex.getMessage());
return null;
}
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 22
96. Worker Implementierung (3)
private String getConfiguredOutput(ComponentContext context) {
String setBy = "default";
Properties props = getBundleContainedProperties(context);
String outputDir = props.getProperty(PROPERTYNAME_OUTPUT_DIR);
if (outputDir != null && outputDir.isEmpty() == false) {
setBy = "in-bundle properties";
} else {
outputDir = (String) context.getProperties().get(PROPERTYNAME_OUTPUT_DIR);
if (outputDir != null && outputDir.isEmpty() == false) {
setBy = "service properties";
} else {
outputDir = DEFAULT_OUTPUT_DIR;
}
}
enunciate("Output Directory is set by "+setBy+" to "+outputDir+".");
return outputDir;
}
...
In-Bundle Properties: nach der Mittagspause
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 23
98. Sonstige Anpassungen
Worker-Impl POM
– Name
– Abhängigkeiten (Worker-API, Enunciator, iText)
GateKeeper
– ServiceTracker für WorkerService
– processFile ruft nächstbesten WorkerService auf
– postResult verkündet asynchron per EventAdmin
– POM: Abhängigkeiten zu Worker-API und OSGi
Service Compendium wegen EventAdmin
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 25
99. Test der Bundles
Aufruf von pax-provision im gossipmonger-Verz.
Ablegen beliebiger XML-Datei in render_input:
GateKeeper: Processing deploy-pom.xml
WorkerServiceImpl: Render from /home/osgi/osgibuch/
gossipmonger/runner/render_input/deploy-pom.xml
WorkerServiceImpl: Rendering...
WorkerServiceImpl: Rendered to /home/osgi/osgibuch/
gossipmonger/runner/render_outpdf/deploy-pom.pdf
GateKeeper: Moving processed file to archive dir ./render_archive
Enunciator-Bundle anhalten (stop <bundle-id>):
stop 5
[...] WorkerServiceImpl: EnunciatorService unset.
Enunciator deactivated.
Enunciator has no LogService; Message is: Enunciator lost
a LogService. Now there are 0 references.
DEBUG biz.gossipmonger.enunciator - BundleEvent STOPPED
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 26
101. Überblick
Sehr ähnlich zu Declarative Services
Standard seit OSGi R4.2
Basiert auf den Ideen von Spring DM 1.0
Spring DM 2.0 ist die Referenzimplementation (RI)
Aktuelle Implementationen sind Apache Aries Blueprint
& Eclipse Gemini Blueprint (Incubator)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
102. Einführung
Verwendung von Legacy Code
Keine Abhängigkeit zur OSGi API
Konstruktor & Setter Injection
Behandlung von OSGI Dynamics
XML-Files befinden sich in OSGI-INF/blueprint
– Alternativer Pfad im Manifest Header definiert:
– Bundle-Blueprint: OSGI-INF/blueprint/config.xml
Verwendung Pax Runner Profil
– Ergänzen von gossipmonger/pom.xml um
<param>--profiles=[...],blueprint</param>
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
103. Blueprint Idee
Application
Application Context
Context
Application
Context
Imported Service
Exported Service
Bean
Blueprint Framework
OSGI Framework
JVM
Spring Dynamic Modules - OSGi with Spring Framework
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
104. Blueprint Bundle
Blueprint Bundle Blueprint Bundle
Metadata Metadata
XML XML
Blueprint Extender
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
105. Blueprint Konfiguration (Auszug)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
108. Überblick
RFC 66: OSGi Web Container Spezifikation
Mächtiger als OSGi HttpService
Web Bundle = Web-Applikation mit OSGi
WAR + OSGi Metadata + Web-ContextPath Header
JEE APIs wie z.B. JPA mit LazyLoading verwendbar
Wrapped WAR Support
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
109. Einführung
Unterstützt WAR und WAB Dateien
WAB benötigt zusätzlichen Manifest Header
– Web-ContextPath: /myServlet
WAR mit URL Handler in ein WAB gewandelt
– Webbundle:file:///myWebapp.war?Web-
ContextPath=/myServlet
Implementation von Spring DM (RI) und Pax Web
Deployment wie jedes andere Bundle
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
110. Applikationsarchitektur
WebApp WebApp
Web Container Bundle 1 Bundle 2
OSGi Framework
Spring Dynamic Modules - OSGi with Spring Framework JVM
Bundles und WebApps sollen Services teilen!
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
114. Agenda
Fragmente
Pax Exam
Einfacher Integrationstest
Erweiterter Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
115. Fragmente
Ergänzen oder erweitern ein Wirts-Bundle
Sind selbst ein Bundle, aber
– nur mit Wirt lebensfähig
– ohne eigenen Class Loader
– ohne BundleActivator
Können beliebigen Inhalt haben
Werden beim Resolve dem Wirt hinzugefügt
Wirt + Fragment = Laufzeit-Bundleinhalt
Einsatz: Übersetzungen, Konfigurationen,
Stylesheets, Skins
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
116. Worker-Konfiguration
Ausgabeordner von WorkerService konfigurierbar
public final class WorkerServiceImpl implements WorkerService {
private static final String BUNDLE_PROPERTIES_FILE = "worker.properties";
private static final String PROPERTYNAME_OUTPUT_DIR = "worker.outputDir";
private static final String DEFAULT_OUTPUT_DIR = "render_output";
String configuredOutput = DEFAULT_OUTPUT_DIR;
...
private String getConfiguredOutput(ComponentContext context) {
String setBy = "default";
Properties props = getBundleContainedProperties(context);
String outputDir = props.getProperty(PROPERTYNAME_OUTPUT_DIR);
if (outputDir != null && outputDir.isEmpty() == false) {
setBy = "in-bundle properties";
} else {
...
}
enunciate("Output Directory is set by "+setBy+" to "+outputDir+".");
return outputDir;
}
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
117. Worker-Konfiguration (2)
...
private Properties getBundleContainedProperties(ComponentContext context) {
Properties properties = new Properties();
URL url = context.getBundleContext().getBundle().
getResource(BUNDLE_PROPERTIES_FILE);
if (url == null) {
enunciate(BUNDLE_PROPERTIES_FILE+" file not found in bundle.");
} else {
try {
InputStream is = url.openStream();
properties.load(is);
is.close();
} catch (IOException e) {
enunciate("Error reading bundle properties file: "+ e.getMessage());
}
}
return properties;
}
...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
118. Erstellen des Fragments
pax-create-bundle im gossipmonger-Verzeichnis
package: biz.gossipmonger.worker
bundleName: biz.gossipmonger.worker-config
bundleGroupId: biz.gossipmonger
version: 0.1.0
src/main/resources/worker.properties erstellen
osgi.bnd mit Fragment-Header
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
119. Fragment nutzen
worker-config POM
– <name>GossipMonger Worker Configuration</name>
– Abhängigkeiten löschen
Aufruf von pax-provision lädt Fragment mit =>
WorkerServiceImpl: EnunciatorService set.
WorkerServiceImpl: activating...
WorkerServiceImpl: Output Directory is set by in-bundle
properties to render_outfragment.
WorkerServiceImpl: activated.
Fragment-Bundle bleibt im Status resolved
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
120. Agenda
Fragmente
Pax Exam
Einfacher Integrationstest
Erweiterter Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
121. Integrationstests
Manuelles Bundle-Testen ist ineffizient
pax-provision ist kein Testverfahren
Bundle-Aktionen sind mit Unit-Tests nicht testbar
– Ausgehende JobTimer-Events
– Reaktion GateKeeper auf JobTimer-Events
– Versand von Nachrichten über den Enunciator
– Korrektes WorkerService-Ausgangsverzeichnis
– Datei für WorkerService bereitstellen
– Renderer-Artefakt (PDF) erstellt
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
122. Pax Exam
Automatisiertes Testen von Bundle-Aktionen
Bundle erstellen für Integrationstest-Modul:
$ mvn archetype:generate
-DarchetypeGroupId=org.ops4j.pax.exam
-DarchetypeArtifactId=maven-archetype-paxexam-junit
-DarchetypeVersion=1.2.0
Metadaten angeben:
groupId: biz.gossipmonger
artifactId: biz.gossipmonger.test.worker
version: 0.1.0
package: biz.gossipmonger.test.worker
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
123. POM anpassen
Parent-Abschnitt wie übrige Bundles ändern
Compiler-Plugin, osgi-core und logging-
Dependency entfernen
SNAPSHOP-Postfixes von Pax-Exam-Deps
entfernen
Alle Projekt-Bundles als Deps eintragen
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
124. Generierter Testfall
Verwendung des Pax Exam TestRunners
BundleContext wird „injiziert“
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 12
125. Agenda
Fragmente
Pax Exam
Einfacher Integrationstest
Erweiterter Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 13
127. Einfacher Integrationstest
Test für WorkerService
Soll PDF-Erstellung anhand InputStream prüfen
Bundles im Test: Enunciator, Worker-API, -Impl
und iText als PDF-Renderer
JobTimer, GateKeeper, Fragment bleiben außen vor
Inputdatei src/test/resources/test.txt anlegen mit
beliebigem Inhalt
SimpleWorkerServiceTest.java im Package
biz.gossipmonger.test.worker erstellen
Benötigte Bundles werden „konfiguriert“
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 15
128. SimpleWorkerServiceTest
@RunWith(JUnit4TestRunner.class)
public class SimpleWorkerServiceTest {
@Configuration
public static Option[] configure() {
return options(
provision(
// Infrastructure bundles
mavenBundle().groupId("org.osgi").artifactId("org.osgi.compendium"),
mavenBundle().groupId("org.apache.felix").
artifactId("org.apache.felix.eventadmin"),
mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.scr"),
// Project bundles
mavenBundle().groupId("biz.gossipmonger").
artifactId("biz.gossipmonger.worker-api").versionAsInProject(),
mavenBundle().groupId("biz.gossipmonger").
artifactId("biz.gossipmonger.worker-impl").versionAsInProject(),
mavenBundle().groupId("biz.gossipmonger").
artifactId("biz.gossipmonger.enunciator").versionAsInProject(),
mavenBundle().groupId("biz.gossipmonger.com.itextpdf").
artifactId("biz.gossipmonger.com.itextpdf.itext").versionAsInProject()
)
);
}
// Test method see next slide
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 16
129. Inhalt Test-Methode
@Test
public void workerServiceResultExists(final BundleContext bundleContext) {
ServiceReference ref = bundleContext.getServiceReference(
biz.gossipmonger.worker.WorkerService.class.getName());
Assert.assertNotNull(ref);
WorkerService worker = (WorkerService) bundleContext.getService(ref);
Assert.assertNotNull(worker);
try {
String filename = "test.txt";
URL url = bundleContext.getBundle().getResource(filename);
InputStream is = url.openStream();
File file = worker.process(is, filename);
Assert.assertNotNull(file);
String filePath = file.getAbsolutePath();
Assert.assertTrue(filePath + " does not exist", file.exists());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 17
130. Integrationstest ausführen
Ggf. Bundles in lokalem Maven-Repo installieren
(mvn install)
Wechsel in Verz. biz.gossipmonger.test.worker
Aufruf von mvn test
Oder: Eclipse -> Run As -> JUnit Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 18
131. Agenda
Fragmente
Pax Exam
Einfacher Integrationstest
Erweiterter Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 19
133. Erweiterter Test
Test der automatisierten Verarbeitung
Input-Datei in Eingangsverzeichnis erzeugen
Nach spätestens 12 Sekunden muss Ergebnisdatei
in konfig. Verzeichnis da sein!
ExtendedWorkerServiceTest.java im Package
biz.gossipmonger.test.worker erstellen
Bundles: wie vorher, zudem JobTimer, GateKeeper,
Worker-Config
Log-Profil
Test auf Felix und Equinox
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 21
134. Erweiterter Test: Beteiligte
@RunWith(JUnit4TestRunner.class)
public class ExtendedWorkerServiceTest {
@Configuration
public static Option[] configure() {
return options(
felix(),
equinox(),
logProfile(),
provision(
...
mavenBundle().groupId("biz.gossipmonger").
artifactId("jobtimer").versionAsInProject(),
mavenBundle().groupId("biz.gossipmonger").
artifactId("biz.gossipmonger.gatekeeper").versionAsInProject(),
mavenBundle().groupId("biz.gossipmonger").
artifactId("biz.gossipmonger.workerconfig").
versionAsInProject().noStart(),
...
)
);
}
// See next slides
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 22
135. Erweiterter Test: Setup
@Before
public void setup(final BundleContext context) {
... // clean or create input dir
String[] top = new String[] { "biz/gossipmonger/gatekeeper" };
Map<String, Object> map = new Hashtable<String, Object>();
map.put(EventConstants.EVENT_TOPIC, top);
context.registerService(EventHandler.class.getName(), new TestEventHandler(),
(Dictionary<String, Object>) map);
... // create test file from scratch in input dir
}
private class TestEventHandler implements EventHandler {
public void handleEvent(Event event) {
System.out.println(event.toString());
resultPath = (String) event.getProperty("output");
}
}
resultPath = Ausgabepfad der gerenderten Datei
Event kommt vom GateKeeper.postResult
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 23
136. Test-Methode
@Test(timeout=12000) klappt leider nicht wegen
Laden der Plattform und Bundles
=> Eigener Sekundenzähler bis 12 (sollte für
JobTimer und zum Rendern reichen)
Zu jeder Sekunde wird resultPath auf Inhalt geprüft
Steht was drin:
– Pfad-Existenz prüfen
– Prüfen, ob Datei
– Prüfen, ob Verzeichnis der Fragment-
Konfiguration entspricht
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 24
137. Test-Methode
@Test
public void workerServiceResultEventOccurs(final BundleContext bundleContext) {
synchronized (this) {
int i = 0;
while (i < 12 && resultPath == null) {
try {
System.out.println("Wait a second (" + ++i + ")");
wait(1000);
} catch (InterruptedException e) {
assertTrue("Testcase was interrupted", false);
}
}
if (i == 12) {
assertTrue("Testcase has timed out", false);
}
}
File file = new File(resultPath);
assertTrue("Result path doesn't exist.", file.exists());
assertTrue("Result path is no file.", file.isFile());
String parentName = file.getParentFile().getName();
assertEquals("Result path is not configured by in-bundle properties file",
"render_outfragment", parentName);
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 25
138. Erweiterten Test ausführen
Ggf. Bundles in lokalem Maven-Repo installieren
Wechsel in Verz. biz.gossipmonger.test.worker
Aufruf von mvn test
Oder: Eclipse -> Run As -> JUnit Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 26
140. Überblick
RFC 119: Remote Services
Produziert Konsumiert
Service A Service A
Services einer Remote Maschine benutzen
– Andere Maschine, verbunden über ein Netzwerk
– Andere JVM, andere Adresse oder Sprache
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
141. Einführung
Sehr dynamisches System
Implementiert durch Eclipse ECF und Apache CXF (RI)
RFC übernimmt die Spezifikation der Schnittstelle
Transport ist Sache des Frameworks
– z.B. Apache CXF → WebServices
Zusätzliche Schritte im vergleich zu lokalen Services
– Registration / Security
– Lookup (Network Discovery)
– Aufräumen
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
142. Konfiguration (Service und Konsument)
service.exported.interfaces
– *
– org.example.BarService,org.example.FooService
service.exported.configs
– org.apache.cxf.ws
– org.apache.cxf.rs
– ecf.generic.server
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
145. Remote LogServer (Standalone)
LogServer implementiert mit Spring DM
META-INF/spring/bundle-context-osgi.xml
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
146. Remote LogClient (enunciator-remote)
Declarative Services
– Default: OSGI-INF/remote-service/remote-services.xml
– Manifest: Remote-Service: META-INF/osgi
Z.B.: Fragment für Enunciator
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
147. Protokoll - Test
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
148. Lab - DOSGi
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
149. DOSGi Discovery
Produziert Konsumiert
Service A Service A
RFC 119 beschreibt einen Weg um Metadata eines
Remote Services zu publizieren/beziehen
Protokolle: Zeroconf/Bonjour, ServiceLocation Protocol
(SLP), Apache Zookeper, Files
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 11
150. Outlook
Aliens - Bundles from
Outer (Java) Space
Oliver Braun
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 1
151. Scala
Vielversprechende Sprache auf der JVM
Hybridsprache OOP + FP
– Objektfunktional / Postfunktional
Natürliche Integration mit Java
Interfaces mit Implementierung -> Traits
Funktionale Programmierung
– Funktionen
– Higher Order Functions
– Pattern Matching („verallgemeinertes switch“)
(fast) Alles kann Alles enthalten
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
152. Reine Objektorientierung
Alles ist ein Objekt
– Keine Primitives in der Sprache (aber auf der JVM)
Int, Float, ...
– Keine besondere Behandlung von Arrays
– Keine static Member => Singleton Objekte
class Example {
...
}
object Example {
...
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
154. Statisch typisiert
Lokaler Typinferenzmechanismus
– Statt in Java:
Map<Integer,String> myMap =
new Map<Integer,String>();
– In Scala
val myMap: Map[Int,String] = Map()
– Oder
val myMap = Map[Int,String]()
– Oder sogar
val myMap = Map(1 -> “eins“, 2 -> “zwei“)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
155. Klassenparameter und „Operatoren“
// Java
class Rational {
final int x; Rational a = new Rational(1,2);
final int y; Rational a = new Rational(2,3);
Rational(int x, int y) { Rational c = a.add(b)
this.x = x;
this.y = y;
}
public Rational add(Rational other) {
return new Rational(x+other.x,y+other.y);
}
}
// Scala
class Rational(x: Int, y: Int) { val a = new Rational(1,2);
def +(other: Rational) = val b = new Rational(2,3);
Rational(x+other.x, y+other.y) val c = a + b
} // a + b
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
156. ScalaModules – DSL für OSGi
// Java
ServiceReference reference =
context.getServiceReference(Greeting.class.getName());
if (reference != null) {
try {
Object service = context.getService(reference);
Greeting greeting = (Greeting) service;
if (greeting != null) {
System.out.println(greeting.welcome());
} else {
System.out.println("No Greeting service available!");
}
} finally {
context.ungetService(reference);
}
} else {
System.out.println("No Greeting service available!");
}
// Scala
context findService withInterface[Greeting] andApply { _.welcome } match {
case None => println("No Greeting service available!")
case Some(welcome) => println(welcome)
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
157. OSGi-Bundle in Scala
package biz.gossipmonger.chirp
import org.osgi.service.log.LogService
import org.osgi.framework.{ BundleActivator, BundleContext,
ServiceReference }
import org.eclipse.scalamodules._
import com.tedneward.scitter._
class Chirp extends BundleActivator {
override def start(context: BundleContext) {
// → next Slide
}
override def stop(context: BundleContext) {}
}
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
159. ... und wie geht's weiter
Anpassen des POM
– Abhängigkeiten zur Scala-Bibliothek, ...
Übersetzen mit Maven
ScalaModules und ScalaBibliothek-Bundles in die
Datei für den Pax Runner
Wegen Scitter noch zusätzliche Abhängigkeiten
Pax Runner starten und los geht's
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10
161. Agenda
Ziele
Spezifikation
Implementierung
Konfiguration
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 2
162. Launcher - Ziele
Java-Applikation
Kein Pax Runner o.ä. notwendig
Selbständiges Laden/Starten der Bundles
Verschiedene Bundle-Quellen nutzbar
Erweiterbar
Wahl der OSGi-Plattform
Debug-Unterstützung
WebStart – Analogie
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 3
163. Launcher – Spezifikation
OSGi Framework Launching API
OSGi Core Specification, Kap. 4.2 Frameworks und 6.2 org.osgi.framework.launch
FrameworkFactory erzeugt System Bundle
Framework-Interface = Bundle-Methoden +
init/start/stop/...
BundleContext nach init() vorhanden
Bundles installieren nach init() möglich
Bundles starten nach start() möglich
waitForStop() blockiert bis Framework-Ende
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 4
164. Implementierung
Launcher ist eigenständiges Projekt
Keine Abhängigkeit zum GossipMonger
Neues Verzeichnis, darin Aufruf von
$ mvn archetype:generate
Choose a number: (...): <default Quickstart>
groupId: biz.gossipmonger
artifactId: biz.gossipmonger.launcher
version: 0.1.0
package: biz.gossipmonger.launcher
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 5
165. POM Abhängigkeiten
Framework-Klasse sollte im ClassPath liegen =>
Framework-Abhängigkeit definieren
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.framework</artifactId>
<version>2.0.2</version>
</dependency>
Infrastruktur-Abhängigkeiten definieren
– Maven-Dependencies mit scope „runtime“
– org.ops4j.pax.url / pax-url-mvn (URL-Handler)
– org.ops4j.pax.url / pax-url-obr (URL-Handler)
– org.apache.felix / org.osgi.service.obr (OBR API)
– org.apache.felix / org.apache.felix.bundlerepository (OBR Admin)
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 6
166. Der Launcher im Groben
System Bundle erzeugen und starten
Bundle-Locations ermitteln und Bundles
aktivieren (installieren und starten) für
– Infrastruktur-Bundles
– Ggf. Debug-Bundles
– Applikations-Bundles
Auf Framework-Ende warten
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 7
167. Implementierung
Framework Factory erzeugen
private FrameworkFactory getFrameworkFactory() throws Exception {
String filename = "META-INF/services/org.osgi.framework.launch.
FrameworkFactory";
List<String> content = getResourceContent(filename);
... // check for exactly one entry
return (FrameworkFactory) Class.forName(content.get(0)).newInstance();
}
– Class.forName für Java < 6
– ServiceLoader.load für Java >= 6
System Bundle erzeugen und starten
FrameworkFactory factory = getFrameworkFactory();
Map<String, String> map = getFrameworkSettings(args);
Framework framework = factory.newFramework(map);
framework.start();
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 8
168. Implementierung
Locations der Infrastruktur-Bundles ermitteln
– Methode getInfrastructureBundles
– liefert List<String> mit Bundle Locations
– Ergebnis: JARs aus „lib“ außer System Bundle
Bundles starten
– Methode activate(context, locations)
– 1. Schleife installiert Bundles:
Bundle b = context.installBundle(location);
– 2. Schleife startet Bundles (Fragmente nicht)
bundle.start();
Analog für Debug und Application Bundles
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 9
169. Launcher – Konfiguration
Framework / Umgebung konfigurieren
META-INF/settings/FrameworkSettings
# The bundle cache shall be cleaned at every start
org.osgi.framework.storage.clean = onFirstInit
...
Debug-Bundles konfigurieren
META-INF/settings/DebugBundles
Applikations-Bundles konfigurieren
META-INF/settings/ApplicationBundles
# Install Apache SCR and Event Admin Service from OBR
obr:org.apache.felix.scr/1.4
obr:org.apache.felix.eventadmin/1
# Install PAX Logging from Maven
mvn:org.ops4j.pax.logging/pax-logging-api/1.4
mvn:org.ops4j.pax.logging/pax-logging-service/1.4
# Install the GossipMonger Bundles from Maven
mvn:biz.gossipmonger/jobtimer/0.2.0
...
OSGi für Praktiker - Bernd Weber, Patrick Baumgartner, Oliver Braun 10