Sie sind auf Seite 1von 27

Prof. Dr.

Oliver Braun | FH Schmalkalden


Christoph Schmidt | FH Schmalkalden

Scala – OSGi-Bundles
from Outer (Java) Space
Inhalt
• Framework / Tools
– OSGi
– Bnd, Pax Runner
– Sbt, ScalaModules, bnd4sbt
• Beispiel: Songfinder
– Code bzw. Vorgehen beim Coden
– Live-Demo
Code unter:
http://github.com/c-schmidt/songfinder_example_wjax
OSGi
• Modulsystem für die JVM
– JSR 291: Dynamic Component
Support for Java SE
– Sichtbarkeitsregeln
– Abhängigkeitsverwaltung
– Versionierung
• Bundles
– JAR + OSGi-Manifest
OSGi
• Dynamisches Komponentenmodell
– Zur Laufzeit: install, start, stop,
update, uninstall
• Serviceorientiertes Modulsystem
– Dienste in JVM zur Laufzeit
registrieren und konsumieren
– Service-Registry für Reaktion auf
Hinzufügen oder Entfernen
OSGi
• Eine Klasse im Bundle muss
Interface BundleActivator
implementieren
• interface BundleActivator {
void start(BundleContext c);
void stop(BundleContext c);
}
• Über BundleContext Services
registrieren, ...
bnd

• „the swiss army knife of OSGi“


• Zum Erzeugen von Bundles
• Generiert Manifest

=> Vereinfacht OSGi-Entwicklung


Pax Runner
• Startet OSGi-Plattform mit
angegebenen Bundles
scan-bundle:mvn:http://scala-
tools.org/repo-releases!
com.weiglewilczek.scala-lang-osgi/scala-
library/2.8.0

$ pax-run.sh
--bootDelegation="sun.*,com.sun.*"
scan-composite:file:songfinder.composite
• Verschiedene Profile
Sbt

• Simple Build Tool


• Konfigurieren und Erweitern in Scala
• Mit interaktiver Shell, z.B.
$ sbt
> ~ compile

• Auch für reine Java-Projekte nützlich


ScalaModules
• Scala-DSL für OSGi-Entwicklung
• Spart eine Menge Boilerplate
// Java
ServiceReference reference =
context.getServiceReference(Greeting.class.getName());
if (reference != null) {
try {
Object service = context.getService(reference);
// Scala Greeting greeting = (Greeting) service;
context findService withInterface[Greeting]
if (greeting != null) { andApply { _.welcome } match {
case None =>System.out.println(greeting.welcome());
println("No Greeting service available!")
case Some(welcome)
} else { => println(welcome)
} System.out.println("No Greeting service available!");
}
} finally {
context.ungetService(reference);
}
} else {
System.out.println("No Greeting service available!");
}
bnd4sbt

• Plugin für sbt zur Nutzung von bnd


• Konfiguration in Scala/sbt
• Kein zusätzliches bnd-File nötig
• Erstellen eines OSGi-Bundles mit
$ sbt bnd-bundle
Der Songfinder
Sbt-Projekt
• Projektverzeichnis:
$ mkdir radio
$ cd radio
• sbt:
$ sbt
Project does not exist, create new
project? (y/N/s) y
Name: radio
Organization: org.unsane.radio
Version [1.0]: 0.1.0
...
Sbt-Projekt
• Konfigurieren des Projekts:
radio/
`-- project
|-- build
| `-- Project.scala
|-- build.properties
`-- plugins
`-- Plugins.scala
Plugins.scala

class Plugins(info: ProjectInfo) extends


PluginDefinition(info) {
lazy val aquteRepo = "aQute Maven Repository" at
"http://www.aqute.biz/repo"
lazy val aquteModuleConfig =
ModuleConfiguration("biz.aQute", aquteRepo)
lazy val bnd4sbt =
"com.weiglewilczek.bnd4sbt" % "bnd4sbt" % "1.0.0"
}
Project.scala
class RadioParentProject(info: ProjectInfo) extends
ParentProject(info) {
object Dependencies {
val osgiVersion = "4.2.0"
val scalaModulesCore =
"com.weiglewilczek.scalamodules" %%
"scalamodules-core" % "2.0.0"
val osgiCore = "org.osgi" % "org.osgi.core" %
osgiVersion % "provided"
}
...
}
Das API-Bundle
als Sub-Projekt:

songfinder-api/
`-- src
`-- main
`-- scala
`-- Songfinder.scala
Erstellen des API-Bundles
• Der Songfinder-Trait:
trait Songfinder {
def find
def remove(songTitle: String)
def stopMsg: String
}

• Bundle in songfinder.composite
aufnehmen
Konfiguration: Project.scala
...
val songfinderAPIProject = project("songfinder-api",
"radio-songfinder-api",
new SongfinderAPIProject(_))
class SongfinderAPIProject(info: ProjectInfo)
extends DefaultProject(info) with BNDPlugin {
override def bndExportPackage =
"org.unsane.radio.songfinder;version=
%s".format(projectVersion.value) :: Nil
}...
Erstellen eines Services
• Ein neues Sub-Projekt:
songfinder-create/
`-- src
`-- main
`-- scala
`-- Activator.scala
• Sub-Projekt in Project.scala
konfigurieren
• Service-Bundle in
songfinder.composite aufnehmen
Erstellen eines Services
//songfinder-create/../Activator.scala
class Activator extends BundleActivator {...
override def start(context: BundleContext) {
val songfinder = new Songfinder {
override def find = {
...
}...
override def stopMsg = "shutdown now!"
}
context createService songfinder
}
override def stop(context: BundleContext) {}
}
Der Watcher

• Ein weiteres Sub-Projekt:


songfinder-watch
• Project.scala konfigurieren
• Client-Bundle in die Datei
songfinder.composite aufnehmen
Der Watcher
//songfinder-watch/../Activator.scala

class Activator extends BundleActivator {


case class Stop()
class WatchActor(context: BundleContext)
extends Actor {…}
private[this] var watcher: WatchActor = _
override def start(context: BundleContext) {
watcher = new WatchActor(context)
watcher.start()
}
override def stop(context: BundleContext) {
watcher ! Stop
}
}
Der Watcher
class WatchActor(context: BundleContext) extends
Actor {
def act() {
println("[radio/songfinder-watch] watching")
context watchServices
withInterface[Songfinder] andHandle {
case AddingService(songfinder, _) =>
songfinder.find
case ServiceRemoved(songfinder, _) =>
println(songfinder stopMsg)
}
receiveWithin(3000) {
case Stop =>
case _ => act()
}
}
Demo
• Im Projektverzeichnis radio

• OSGi-Plattform mit Pax Runner starten:

$ pax-run.sh
--bootDelegation="sun.*,com.sun.*"
scan-composite:file:songfinder.composite
Quellen
http://github.com/c-
schmidt/songfinder_example_wjax

http://github.com/weiglewilczek/scalamodules
http://github.com/weiglewilczek/bnd4sbt
http://code.google.com/p/simple-build-tool/
http://www.osgi-buch.com/
http://paxrunner.ops4j.org/space/Pax+Runner
Und zum Schluss ein kleines
bisschen Werbung:
Vielen Dank für Ihre
Aufmerksamkeit
c.schmidt@stud.fh-sm.de
http://github.com/c-schmidt

o.braun@fh-sm.de
http://pads.fh-schmalkalden.de/
http://twitter.com/obcode
http://github.com/obcode
http://slideshare.net/obcode