osgi component programming | oopsla 2006 © 2006 by ibm, aqute & osgi alliance; made available...

109
1 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 Copyright is held by the OSGi Alliance, IBM and aQute This presentation is made available under the EPL v1.0 OOPSLA'06, October 22–26, 2006, Portland, Oregon, USA. 2006 ACM 06/0010.

Upload: riley-adams

Post on 27-Mar-2015

217 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

1 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Copyright is held by the OSGi Alliance, IBM and aQute

This presentation is made available under the EPL v1.0

OOPSLA'06, October 22–26, 2006,

Portland, Oregon, USA.

2006 ACM  06/0010.

Page 2: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

2

© 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OOPSLA 2006 Portland

© 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OOPSLA 2006 Portland

OSGi Component Programming

Peter KriensOSGi Technical DirectorOSGi EvangelistCEO [email protected]

Page 3: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

3 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Content

Section I – Setting Up Eclipse and the OSGi Platform

Section II – OSGi Background

Section III – OSGi Technology

Section IV – Fundamental OSGi Concepts

Section V – Component Interaction and Collaboration

Section VI – Service Components

Section VII – Use Case: Developing a Chat Service

Section VIII – Service Tracking

Section IX – Finishing Touch

Section XI – Final

Page 4: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

4 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section I – Setting up Eclipse and the OSGi Platform

Page 5: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

5 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Setup: A Clean Workspace in Eclipse

Page 6: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

6 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Setup: Your Infrastructure

You need to have the following software installed on your machine in a new workspace:

Latest Eclipse SDK (3.2 or 3.3) (http://www.eclipse.org) The tutorial projects from CVS:

Server: bundles.osgi.org Repository /cvshome/bundles User tutorial Password fun Projects tutorial-01

The bnd plugin installed

You can install all this from CVS or from the CD

This tutorial assumes the PC for user interface interactions. You must translate this to your environment if you run Linux or have a Mac

Page 7: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

7 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Loading the Tutorial Projects from CVS

In Navigation View, open context menu, and select Import (* > Import

* is context menu, select file, use right mouse (on the PC)

This opens a dialog

Select CVS > Projects from CVS, then Next

You might get a window to choose from a repository, create a new repository in that case

Fill in the repository information from the previous slide (password=fun) > Next

Page 8: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

8 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Loading the Tutorial Projects from CVS

In CVS Repositories view, expand: tutorial-01

Click on + to expand

Select all projects under tutorial-01

Select with the mouse and hold the shift key pressed to select multiple

choose Next > Check Out > Finish

Page 9: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

9 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Your Workspace (More or Less)

Page 10: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

10 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Install the bnd Plugin

Copy in the OS the bnd.jar file to your eclipse/plugin directory related to your running eclipse.exe.

The bnd.jar file resides in the aQute.tutorial.runtime project in the jar directoryCopy this from your operating system

Exit Eclipse and restart

Verify: Help > About > Plugin Details

Check for “aQute Bundle Tool”

The bnd bundle/plugin provides a convenient way to make bundles.

It adds a menu to files that have a “.bnd” extensionThe bnd file contains all the information a requires, it calculates defaults for undefined informationThe bnd.jar is also usable as a command line option

For more documentation, http://www.aqute.biz/bnd

Page 11: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

11 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section II - OSGi Background

Page 12: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

12 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What is the OSGi Service Platform?

A Java framework for developing (remotely) deployed service applications, that require:

Reliability

Large scale distribution

Wide range of devices

Collaborative

Created through a collaboration of industry leaders

IBM, Ericsson, Nokia, Sony, Telcordia, Samsung, ProSyst, Gatespace, BenQ, Nortel, Oracle, Sybase, Espial, and many more

Spec 4.0 publicly available at www.osgi.org …

Cool!

Page 13: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

13 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Why the OSGi Service Platform?

What problems does the OSGi Service Platform address?

The limited (binary) software portability problem

The complexity of building heterogeneous software systems

Supporting the myriad of configuration, variations, and customizations required by today’s devices

Managing the software on the device

Page 14: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

14 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Problems: Limited Binary Software Portability

Lack of portability causes

Market friction: No large market of reusable components and applications

Reduced quality

Unnecessary constraints on hardware and software architectures

CPUs differ widely in cost and performance

Linux is nice, but it is sub-optimal for smaller devices

Benefits of the OSGi Platform

Applications run unmodified on different hardware and software architectures due to a formal specification of all relevant aspects

The OSGi Specifications gives you choice!

Page 15: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

15 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Problems: Complexity of SoftwareP

rodu

ctiv

ity

Complexity and Size

Assembly

Structured Programming

Service Oriented Programming

Page 16: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

16 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Problems: Limits of Object Oriented Technology

Objects are great, but oh, the tangled webs we weaves …

Coupling severely limits reusability

Using a generic object, can drag in a large number of other objects

Creates overly large systems after a certain complexity is reached

Flexibility must be built in by the programmer

Plug-in architectures

Component architectures like OSGi minimize the coupling that is created by OO

Page 17: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

17 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section III - OSGi Technology

Page 18: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

18 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The OSGi Framework Architecture

Allows applications to share a single Java VM

Handles all class loading in a much better defined way than standard Java Versioning!

Gives isolation/security between applications

Mediates between communication & collaborations between applications

Provides life cycle management (install, start, stop, update, etc).

Policy free Policies are provided by bundles

Operating SystemOperating SystemOperating SystemOperating SystemOperating SystemOperating System

Operating SystemOperating System

JavaJavaVMVMJavaJava

VMVMJavaJavaVMVMJavaJava

VMVM

JavaJavaVMVMJavaJava

VMVMJavaJavaVMVMSystem Class LibrariesSystem Class Libraries

OSGiOSGi

OSGiOSGiOSGiOSGi

OSGiOSGi

ApplicationApplicationApplicationApplication

ApplicationApplication

ApplicationApplicationApplicationApplication

ApplicationApplicationApplicationApplication

LibraryLibrary

Page 19: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

19 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The OSGi Platform is a Service Oriented Architectures (SOA)

Separate the contract from the implementation

Allows alternate implementations

Dynamically discover and bind available implementations

Binding based on contract (interface definitions)

Components are reusable

Components are not coupled to implementation details of other components, only their independent interfaces have to be known

Service Contract

Componentprovides

uses

Page 20: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

20 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OSGi Service Platform Layering

The OSGi Service Platform is divided in a number of layers

Execution Environment provides a defined context for applications

The Module layer provides class loading and packaging specifications

The Services layer provides a collaboration model

The extensive Security layer is embedded in all layers

Module

Life Cycle

Services

Sec

urity

Execution EnvironmentA

pplic

atio

ns

Page 21: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

21 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: OSGi Execution Environment

Define the class library available from the VM java.* classes Additional constraints

OSGi APIs use only a subset of Sun’s J2SE and J2ME CDC/CLDC

OSGi Minimum EE

Matches most Java profiles

Implementations can use more than the OSGi Minimum EE

Security is not mandatory

CLDC is possible if class loaders are added in a device specific way

CLDC/MIDP

J2SE

CDC/FP

OSGiMin.

Page 22: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

22 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: OSGi Module Layer

Packaging of applications and libraries in Bundles

Java has significant deployment issues

Class Loading modularization

Java provides the Class Path as an ordered search list, which makes it hard to control multiple applications

Protection

Java can not protect certain packages and classes from others

Versioning

Java can not handle multiple versions of the same package in a VM

bundle

bundlebundle

bundle

bundle

bundle

bundle

Page 23: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

23 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: OSGi Life Cycle Layer

System Bundle represents the OSGi Framework

Provides an API for managing bundles

Install

Resolve

Start

Stop

Refresh

Update

Uninstall

BundleX

BundleX-v2

BundleB

BundleM

BundleA

Systembundle

State (active or not)

Manages

Page 24: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

24 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: OSGi Life Cycle Layer

Bundle is started by the Bundle Activator class

Header in the JAR manifest file refer to this class

Bundle Activator interface has 2 methods Start: Initialize and return immediate Stop: Cleanup

The Bundle Activator gets a Bundle Context that provides access to the OSGi Framework functions

The Framework provides the Start Level service to control the start/stop of groups of applications

INSTALLED

RESOLVED

UNINSTALLED

ACTIVE

STOPPING

STARTING

start

stop

Page 25: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

25 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: OSGi Service Layer

Provides an inside-VM service model

Discover (and get notified about) services based on their interface or properties, no protocol required

Bind to one or more services by

program control, default rules, or deployment configuration

Service Oriented Architectures (SOA) Confusion

Web services bind and discover over the net

The OSGi Service Platform binds and discovers inside a Java VM

The OSGi Alliance provides many standardized services

Page 26: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

26 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: The OSGi Service Layer Evolution

UPnPInitial ProvisioningName SpaceJiniStart LevelIO ConnectorWire AdminXML ParserMeasurement & StatePositionExecution Env.

Application ManagerForeign App. AccessSigned BundlesDeclarative ServicesDevice ManagementSecurity PoliciesFramework LayeringInitial ProvisioningUPnPConditional Permissions…

2000 2001 2003 2006

R1

R2

R3

R4H

om

e A

uto

ma

tio

n

Ve

hic

le

Mo

bil

e

FrameworkHttpLogDevice Access

Package AdminConfiguration AdminPermission AdminUser AdminPreferencesMetaTypeService Tracker

R5

Page 27: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

27 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Layers: The Security Layer

The OSGi Service Platform can be configured to be one of the most secure execution environments

The security model is dynamic, unlike normal Java

Fully under control of the operator

Fully controlled systems

Walled gardens

Fully open systems

Based on Java 2 security

Permissions

Bundle signing

A number of extra rules to increase the overall system security

Page 28: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

28 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The OSGi Implementations

Major Framework vendors are

ProSyst,

Gatespace Telematics, and

IBM

Siemens

Espial

Open source implementations

Apache Felix

Eclipse Equinox

Gatespace Knopflerfish

See http://www.aqute.biz/osgi for an overview

Page 29: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

29 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Benefits of the OSGi Service Platform

Components are smaller

Easier to make

Components are minimally coupled to other components

Gives reusability

Collaborative model

Allows reuse of other components for most problems

Wide Adoption

Bigger market, more components available

Excellent model for the myriad of customizations and variation that are required of today’s devices

Page 30: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

30 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

The OSGi Service Platform is kind of a Java Operating System

Execution Environment

Module layer

Service Layer

Security

It simplifies:

Deployment Problems

Software composition

Software management

The OSGi technologies are implemented by many vendors and open source groups.

Page 31: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

31 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section IV - Fundamental OSGi concepts

Page 32: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

32 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Framework Entities

OSGi Framework

Bundle A{…}

= service, defined by java interface

Bundle B{…}

Bundle C{…}

= bundle

Page 33: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

33 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Bundles

A bundle is the deliverable application

Like a Windows EXE file

Content is a JAR file

A bundle registers zero or more services

A service is specified in a Java interface and may be implemented by multiple bundles

Services are bound to the bundle life-cycle

Searches can be used to find services registered by other bundles

Query language

Bundle A{…}

Bundle B{…}

Page 34: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

34 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What is in a Bundle?

A Bundle contains (normally in a JAR file): Manifest (bundle meta data) Code (classes in packages) Resources (other files in the JAR file)

The Framework: Reads the bundle’s manifest Installs the code and resources Resolves dependencies Controls the bundle life cycle

During Runtime: Calls the Bundle Activator to start the bundle Manages java class path for the bundle as a network of class loaders Handles the service dependencies Calls the Bundle Activator to stop the bundle Cleans up after the bundle

Bundle A{…}

Page 35: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

35 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Create a Hello (and Goodbye) World Bundle

* > New > Project

Java Project > Next

Fill in the information, defaults are likely to be ok. As name you can use my.world, then > Next

For each tab:Source, just infoProjects, for dependent projects. We have none nowIn Libraries > Add JARs, add a JAR from project aQute.tutorial.runtime, directory work/osgi.jar. This Provides the OSGi interfaces on the class path for the bundle

> Finish

Page 36: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

36 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Create a Hello (and Goodbye) World Bundle

Page 37: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

37 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Create a Hello (and Goodbye) World Bundle

Create a Java source called World.java

Select src folder * > New > Class

Set the package to something like my.world

Add the BundleActivator interface to the Interfaces list box.

Check the “Inherited abstract methods” checkbox, this will generate the start and stop methods for the BundleActivor interface

The remaining examples use the package names of the provided source code, no longer my.world. You should choose your own naming to not conflict with the provided source code.

Page 38: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

38 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Source code for Hello/Goodbye World

The source should look similar to the source placed adjacent

We have to fill in the // TODO blocks

start – Called when the bundle is started

stop – When the bundle is stopped (no guarantee though!)

Some tips

F3 > Will jump to the selected type (try, click BundleActivator, and then F3)

Control-Shift-T > Will show a source of a type (class)

Control-Shift-R > Will show a source of a resource (not a class)

package aQute.tutorial.world;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator {

public void start(BundleContext context) throws Exception {

// TODO Auto-generated method stub}

public void stop(BundleContext context) throws Exception {

// TODO Auto-generated method stub}

}

Activator.java

Page 39: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

39 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Manifest code for Hello/Goodbye World

Each JAR file has a manifest

Basic format of the manifest is defined by Sun http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html

A manifest is a text file that provides meta information about the JAR file. Used for versioning and JAR file signing.

A manifest consists of a set of headers and values. For example, Manifest-Version: 1

Unrecognized headers are ignored by the Java VM, this makes it possible to extend the manifest

The OSGi specifications have declared manydifferent headers Vendor information Imported and Exported packages Native code …

Page 40: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

40 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Real code! Hello World (and Goodbye)

A bundle needs a manifest. The bnd plugin can create this for you (and verify its headers for validity!)

You have to create a bnd file in the project directory. * > New > File

aQute.world.bnd, pick your own name if you want

Add:Export-Package. Defines the packages that should be included in your bundle You can use wildcardsBundle-Activator, aQute.tutorial.world.Activator

Adjust the package names to your earlier choice!

Create the bundle by selecting the bnd file, then * > Make Bundle

This creates a JAR file, which is your first bundle!

Export-Package: aQute.tutorial.worldBundle-Activator: \ aQute.tutorial.world.Activator

aQute.tutorial.world.bnd

Page 41: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

41 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Bnd Plugin Translation

The bnd plugin translates the aQute.tutorial.world.bnd file to the manifest, and embeds in the JAR file

Any header that starts with an uppercase character is copied to the manifest by bnd

Crucial headers will be filled in by bnd if you do not define a value

Import-Package is calculated from the referred classes and matched, for example:

* (all) is default!com.acme.* means do not import

Export package expressions are matched against all packages on the class path

Full manual: http://www.aqute.biz/bnd

Manifest-Version: 1Bundle-Name: aQute.tutorial.worldBundle-Activator: \ aQute.tutorial.world.ActivatorImport-Package: aQute.tutorial.world, \ org.osgi.framework;version=1.3Bundle-ManifestVersion: 2Bundle-SymbolicName: \ aQute.tutorial.worldExport-Package: \ aQute.tutorial.world; \ uses:=org.osgi.framework

META-INF/MANIFEST.MF

Export-Package: aQute.tutorial.worldBundle-Activator: \ aQute.tutorial.world.Activator

aQute.tutorial.world.bnd

bnd

Page 42: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

42 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Launch a Framework

Run -> Run …

Select EquinoxFw The launch file is provided by the aQute.tutorial.runtime

project.

This starts an Equinox Framework with the fileinstall.jar bundle as only bundle.

The fileinstall.jar bundle watches the work directory for bundles Any bundle in this directory will be installed and started Removed bundles will be uninstalled This is not an OSGi “standard”, it is just an application like for

example Eclipse!

Installing and uninstalling is therefore simply managing the aQute.tutorial.runtime/work directory

Page 43: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

43 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Launching EquinoxFw

Page 44: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

44 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Run the Hello World bundle

The launch runs a Framework console

Just copy (drag and drop or * > Copy and > Paste) the aQute.tutorial.world.jar to the work directory

See the “Hello World” appear in the console

Type “ss” (show status)Look at the active bundlesNotice the number for the aQute.tutorial.world.jar bundle. This is the bundle-id.

Type “stop <bundle-id>”

See the “Goodbye world”

The “Hello World” appears again because the fileinstall.jar bundle starts the bundle again because it is still in the work directory.

Page 45: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

45 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Eclipse Self Hosted Target Environment

Eclipse also provides the Plugin Development Environment (PDE) besides the Java Development Environment (JDE) that we used so far.

Plugins are bundles and the PDE is therefore usable to make bundles

Handles dependencies Generates JARs Launches an Equinox Framework form a Target definition

However, I find this environment hard to use for more general bundle development (I tried!)

Easy to confuse the class path management JAR generation is complex and manual No extensive checks on generated bundles Cannot include packages form other sources than project

Page 46: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

46 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

The unit of deployment of an OSGi Service Platform is a bundle

How to create a bundle with the bnd plugin

How to launch an Equinox environment with a defined set of bundles, and manage it with the fileinstall.jar bundle

How to start/stop bundles

How the Equinox console works

Why the Eclipse Self Hosting is not used

Page 47: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

47 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section V – Component interaction and collaboration

Page 48: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

48 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Collaborative model

OSGi is more than an Applet, MIDlet, Xlet runner

Bundles can collaborate through:

service objects

package sharing

A dynamic registry allows a bundle to find and track service objects

Framework fully manages this collaboration

Dependencies, security

Page 49: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

49 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Collaborative model

BundleBundle

JAVA

Operating System

Hardware

OSGi Framework

Serviceregistry

packagespackages

Page 50: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

50 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Collaborative model

JAVA

Operating System

Hardware

Java Application Manager

Serviceregistry

packagespackages

Midlet,Xlet,

orApplet

Midlet,Xlet,or

Applet

No native code

No package management(versions!)

No collaboration

No management bundles

Page 51: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

51 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Class Path Issues

Java applications consists of classes placed in packages

Java searches for a class in different jar files and directories

These are usually specified in the CLASSPATH environment variable

An OSGi Framework is a network of class loaders that delegate by the package name. The class loaders are parameterized by the manifest headers.

Any dependencies between bundles are resolved by the OSGi Framework

Complicated – But an OSGi Framework makes it painless to use

See the uses: directive illustrated in this slide

The bnd plugin makes it easy to generate the right information

q

p

r

p

q-1.0

q

q-2.0

Exported package

Exported package Wire

Constraint

Page 52: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

52 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OSGi Package Dependency Resolution

Bundle AExport org.osgi.service.log com.ibm.service.log com.ibm.j9Import org.osgi.service.http javax.servlet.http

Framework org.osgi.framework org.osgi.service.http

Bundle BExport ericsson.osgi javax.servlet javax.servlet.http org.osgi.service.logImport org.osgi.service.http

B resolved

A resolved

Page 53: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

53 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Package or Bundle Dependencies?

The OSGi Specifications supports both Require-Bundle and Import-Package

Require-Bundle creates a dependency on a complete bundle

Simple to useImports packages that are never used

Import-Package creates a dependency on just a package

Creates less brittle bundles because of substitutabilityMore cumbersome to use (Tools!)The bnd utility takes the pain out of this

In almost all cases, Import-Package is recommended because it eases deployment and version migration

The specifications detail a number of additional problems with Require-Bundle

r

r

s

r

q

p

Require-Bundle

Import-Package

Page 54: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

54 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Service Specifics

A service is an object registered with the Framework by a bundle to be used by other bundles

The semantics and syntax of a service are specified in a Java interface

A bundle can register a service.

A bundle can use a service (bind to) with any cardinality 1..1, 0..1, 0..n

A service can be discovered dynamically Active search with query filter Listener interface

Services can go away at any time! This is very dynamic!

service

bind register

listen

package org.osgi.service.log;import org.osgi.framework.ServiceReference;public interface LogService { static final intLOG_ERROR= 1; static final intLOG_WARNING= 2; static final intLOG_INFO= 3; static final intLOG_DEBUG= 4;

void log(int level, String message); void log(int level, String message, Throwable exception); void log(ServiceReference sr,int level, String message); void log(ServiceReference sr, int level, String message, Throwable exception);}

Page 55: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

55 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Service Specifics

The Framework Service Registry is available to all bundles to collaborate with other bundles

Different bundles (from different vendors) can implement the same interface Implementation is not visible to users Allows operator to replace implementations without disrupting service

OSGi defines a standard set of services Other organizations can define more (AMI-C, Ertico, JCP)

Extensive notifications for service life cycles

Services have a unique id

Services can require Service Permission if security is enabled Fully under operator control

Services are associated with properties Powerful query language to find appropriate service Bundles can update the properties of a service dynamically

Page 56: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

56 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Manipulating Services

The Bundle Context provides the methods to manipulate the service registry

Services registrations are handled by Service Registration objects

They can be used to unregister a service or modify its properties

Service Reference objects give access to the service as well as to the service’s properties

Access to service objects is through the getService method. These services should be returned with the ungetService method

ServiceRegistration registerService( String clss, Object srvc, Dictionary prprts)

ServiceReference[] getServiceReferences( String clss, String fltr)

Object getService( ServiceReference reference)

boolean ungetService( ServiceReference rfrnc);

Page 57: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

57 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Services and Best Practice

Subsystem binding, like a Log Service for example

Separate your code in POJOs (Plain Old Java Objects) that are not coupled to OSGi technology, and an Bundle Activator that binds the POJOs in the desired way

Use declarative services to handle the binding (discussed later)

Domain objects, like a Bluetooth service that is registered when a Bluetooth device comes into range

Use the Service Tracker class for these situations

Handle the dynamics, dynamic things will happen

Start Level service is not a way to handle dynamics, believe me

You can not control the initialization order, believe me

Page 58: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

58 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

The OSGi Service Platform provides a collaboration model that is based on

Services

Package sharing

Sharing is complicated, but the well defined specifications make it quit painless for bundle developers

Services provide a very powerful dynamic programming model

SOA, without the communication overhead!

Page 59: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

59 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section VI – Service Components

Page 60: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

60 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Declarative Services Simplify Service Programming

The dynamic nature of services make programming more complicated

The declarative service model simplifies handling these dynamics

Dependencies are defined in an XML file or via bnd (which translates it to an XML file in the bundle, so the result is the same)

Declarative Services:

Optionally Depend on one or more services

Optionally Provide a service

Optionally lazy initialized

Configurable

Example shows a hello world bundle that logs “Hello” and “Goodbye” to the Log Service

Service-Component: \ aQute.tutorial.component.World; \ log=org.osgi.service.log.LogServiceExport-Package: aQute.tutorial.component

aQute.tutorial.component.bnd

(bnd only)Service-Component ::= clause ( ‘,’ clause ) *clause ::= definition | <resource path>definition ::= <class-name> ( ‘;’ ‘dynamic:=‘ list ) ? ( ‘;’ ‘optional:=‘ list ) ? ( ‘;’ ‘multiple:=‘ list ) ? ( ‘;’ name ‘=‘ <interface-name> ) *

<?xml version="1.0" encoding="utf-8" ?> <component name="aQute.tutorial.component.World"> <implementation class="aQute.tutorial.component.World"/> <reference name="log" interface="org.osgi.service.log.LogService" bind="setLog" /> </component>

OSGI-INF/aQute.tutorial.component.World.xml

Page 61: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

61 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Component Source Code

A component can be any class. No specific interface implementation is required.

The activate and deactivate protected methods are called when the component is activated and deactivated

Dependencies must be resolved. References can be bound to the component by calling the setXXX method

Bnd will invoke a setXXX method when the reference name is lower case. The unsetXXX method is invoked when the policy is also dynamic.

The Component Context class provides access to referenced services by name. The locateService method finds a reference by name

The component instance can be sure that at any moment in time between activate and deactivate there is a valid Log Service in this example

package aQute.tutorial.component;import org.osgi.service.component.*;import org.osgi.service.log.LogService;

public class World {LogService log;protected void activate(

ComponentContext context) { log.log(LogService.LOG_INFO,

"Hello World"); }protected void deactivate(

ComponentContext context) { log.log(LogService.LOG_INFO,

"Goodbye World"); }public void setLog(LogService log) {

this.log = log; }}

<?xml version="1.0" encoding="utf-8" ?> <component name="aQute.tutorial.component.World"> <implementation class="aQute.tutorial.component.World"/> <reference name="log" interface="org.osgi.service.log.LogService" bind="setLog" /> </component>

OSGI-INF/component.xml

Component.java

Page 62: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

62 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Launching

Launch the EquinoxFw launch configuration

You can look in the log with the log command. Enter:

osgi> logLast event is at bottom, so scroll back

Find the “Hello World”

Stop the bundle

Enter in the console: osgi> stop <bundle-id>

Run log again

Page 63: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

63 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

Programming with services can be complicated

The Declarative Services model makes service programming much, much, simpler

How the component XML is constructed

How bnd provides a simplified syntax

How to use the Log Service

Page 64: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

64 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section VII – Use Case: Developing a Chat Service

Page 65: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

65 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

A Chat Service

A Chat client should be able to communicate with a user through:

A window, telnet session, MSN, AOL, Skype, etc. interface.

We base the communication between chat clients on a Channel service.

The registrar of the service receives the messages

The getter of the service sends the message

A property contains the user name to identify the service

Two services are used to communicate

For simplicity, we use a command based interface for login and listing buddies

Channel servicesend(from,msg)

Chatsend

Chat receive

Petersession

Petersession

Thomas session

Thomas session

Channel services

message

Page 66: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

66 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Channel Service Design

Create a new project to hold our service interface

Call this project <myname>.chatThis is a Java Project

The Channel service is one way: The registrar receives through a Channel service!

A service property is defined. This property must be registered with the service

CH_NAME – This must be set to the name of the user, e.g. “pkriens”

A single method send with the following arguments

from – The user name that sends the message. There normally should be a Channel service with that CH_NAMEmsg – The message to be send

Export the aQute.tutorial.chat package in the bnd file.

Create your JAR with * > Make Bundle, and copy it to the runtime work directory to install it.

package aQute.service.channel;import java.io.*;public interface Channel {

String CH_NAME="channel.name";

void send(String from, String msg) throws IOException ;}

Channel.java

Export-Package: aQute.service.channel

aQute.tutorial.chat.bnd

Page 67: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

67 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Good Pattern: Whiteboard Approach

What we use in the Channel service is the “Whiteboard Approach”.

Based on Inversion of Control (IoC) pattern:Don’t call us, we will call youIt is very effective because it reduces the number of couplings between bundles

Pattern:Register a serviceLet any interested bundle use it

The Whiteboard approach was discovered during finishing of R1. We were not brave enough to scrap, that is why the Log Service and Http Service are not white board

There is a white-paper comparing a whiteboard approach with a non whiteboard approach.

http://www.osgi.org/documents/osgi_technology/whiteboard.pdf

Bundle A{ }

register

Serverbundle

Events: register,unregister,modified

Bundle C{ }

Bundle B{ }

Publisher

bind

Page 68: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

68 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Telnet Based Chat Client

The best way to find out if this works is to design a small test program.

The easiest way for a “UI” is a telnet server that uses the Channel service to communicate with siblings

This also shows how Internet server daemons should be constructed

The Telnet Chat server will create a Handler for each opened session.

The Handler is a thread that waits for input from the userThe Handler registers a Channel service.

The Handler is stopped when the session closes (user quits or the connection is lost).

This must unregister the Channel service

TelnetChatTelnetChat

HandlerHandler

ChannelChannel

LogServiceLogService

Activated by Declarative Services

ThreadThread

User

For each session1

*

Class Diagram

= Service Interface

Page 69: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

69 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The TelnetChat Manifest

Create a new Java project for a telnet chat

Call this project <myname>.telnetchat

Add the osgi.jar from the aQute.tutorial.runtime/work directory to your project for the OSGi interfaces

Define the <myname>.telnetchat.bnd file

We only specify a reference to the Log Service

Notice that we use upper case, for demo reasons. Bnd does not create set and unset methods when the name starts with uppercase.

Export-Package: aQute.tutorial.telnetchat.*Service-Component: \ aQute.tutorial.telnetchat.TelnetChat; \ LOG=org.osgi.service.log.LogService

aQute.tutorial.telnetchat.bnd

Page 70: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

70 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The TelnetChat Component code

Create a new source for the TelnetChat server.

No interfaces, no extends

The code does not show the import packages and field definitions

The source code is provided for you in aQute.tutorial.telnetchat

Control-Shift-O organizes your imports! Good exercise

The activate method: Remembers the Bundle Context for later Gets the Log Service Starts the Thread.

The deactivate method: Sets the quit flag so any loops in the started Thread will finally end. Threads can not be stopped.

Closes all created Handler objects Exceptions are ignored because we are

closing And closes the Server Socket object, this will

surely quit the main socket accept loop.

protected void activate( ComponentContext context) { this.context = context; log = (LogService) context .locateService("LOG"); start();}

public void deactivate( ComponentContext context) throws Exception { quit = true; for (Iterator i = handlers.iterator(); i .hasNext();) { Handler handler = (Handler) i.next(); try { handler.close(); } catch (Throwable e) { // We are closing } } server.close();}

TelnetChat.java

Page 71: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

71 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The TelnetChat run method

The run method creates a Server Socket and accepts incoming connections.

For bundles, it is crucial that this loop never quits, but also not overloads the system by trying continuously

There is usually no user watching a server …

The outer loop therefore catches errors, sleeps and tries again

A lot of problems disappear over time. For example, an Internet connection can be temporarily down

The Server Socket has a timeout to check the flag regularly, extra safety

The inner loop Wait for an incoming Socket Creates a Handler object And starts the Handler’s Thread

public void run() { while (!quit) try { server = new ServerSocket(2030); server.setSoTimeout(1000); loop(); } catch (Exception e) { log .log( LogService.LOG_ERROR, "[TelnetChat] Inn…", e); sleep(10000); }}void loop() throws Exception { while (!quit) try { Socket socket = server.accept(); Handler handler = new Handler(context .getBundleContext(), socket, this); handlers.add(handler); handler.start(); } catch (SocketTimeoutException e) { // Just for checking the quit flag // at a regular basis }}

TelnetChat.java

Page 72: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

72 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

TelnetChat convenience methods

Convenience methods void remove(Handler handler) { handlers.remove(handler);}void sleep(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e1) {}}

TelnetChat.java

Page 73: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

73 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Handler Source Code

Create a Handler.java file

The constructor receives the Socket for the session with the end user. It initializes:

The fieldsA Writer object to send text to the end user

The send method writes the message in the Writer object and flushes it to ensure the user sees it

The close method closes the different objects and quits the main loop:

By setting the quit flagBy closing the Socket

Closing the Socket of a listener thread is a crude but sure way to get the Thread’s attention

public Handler(BundleContext context, Socket socket, TelnetChat activator) throws Exception { this.ctxt = context; this.socket = socket; this.parent = activator; writer = new PrintWriter( new OutputStreamWriter(socket .getOutputStream()));}public void send(String source, String msg) throws IOException { writer.println(source + "> " + msg); writer.flush();}void close() { try { quit = true; writer.close(); socket.close(); } catch (IOException e) { // Ignore in close }}

Handler.java

Page 74: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

74 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Handler Source Code

The run method loops as long as there is input from the user. It quits when the Socket is closed or an error occurs.

Errors are only logged when the session has not quit because there are usually Socket errors during closing

The finally clause is used to guarantee that the Handler is removed from the parent when it is closed.

If a valid line is received, it is send to the process method

The line is cleaned from nasty characters and backspaces (for telnet clients that send character by character).

public void run() { writer .println("Welcome…Telnet Chat"); writer.flush(); try { InputStreamReader srdr = new InputStreamReader( socket.getInputStream()); BufferedReader reader = new BufferedReader( srdr); while (!quit && (line = reader.readLine()) != null){ process(clean(line)); } writer.println("bye"); } catch (Exception e) { parent.log.log(LogService.LOG_ERROR, "reading user input", e); } finally { parent.remove(this); parent = null; close(); }}

Handler.java

Page 75: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

75 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Handler Source Code

The process method handles a line of input from the user. It checks the line against the /login or /quit command.

Simplistic, I know

If the line starts with /quit, we quit the program by setting the quit flag.

Otherwise we assume it is a line we need to send to another user, which is handled in the dispatch method

void process(String line) throws Exception { if (line.startsWith("/login")) login(line); else if (line.startsWith("/quit")) quit = true; else dispatch(line);}void login(String line) throws IOException { String parts[] = line.split("\\s"); if (parts.length != 2) send("error", "/login <name>"); user = parts[1]; if (channel != null) channel.unregister(); Dictionary properties = new Hashtable(); properties.put(Channel.CH_NAME, user); channel = parent.context .getBundleContext().registerService( Channel.class.getName(), this, properties);}

Handler.java

Page 76: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

76 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Handler Source Code

The dispatch method parses the destination name from the input

For this name , finds a Channel service n

It then sends the remainder of the line to that service with the send method of that service

void dispatch(String line) throws Exception { try { String parts[] = line.split("\\s+"); ServiceReference channels[] = ctxt .getServiceReferences( Channel.class.getName(), "(" + Channel.CH_NAME + "=" + parts[0] + ")"); if (channels != null) { Channel toChannel = (Channel) ctxt .getService(channels[0]); toChannel.send(user, line.substring( parts[0].length()).trim()); ctxt.ungetService(channels[0]); } else { send("error", "no such user: " + parts[0]); } } catch (Exception e) { send("error", "problems: " + e); }}

Handler.java

Page 77: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

77 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Handler Source Code

The clean method cleans up the input if backspaces were used

Also ignores non ASCII characters

String clean(String line) { byte[] buf = line.getBytes(); int out = 0; for (int in = 0; in < line.length(); in++) { char c = line.charAt(in); if (c == '\b') // backspace out--; else if (c >= 32 && c < 0x7F) buf[out++] = (byte) c; } return new String(buf, 0, out);}

Handler.java

Page 78: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

78 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Run the Telnet Chat

Do * > Make Bundle on the aQute.tutorial.telnetchat.bnd file

Copy your resulting bundle to the aQute.tutorial.runtime/work directory to get it installed

Create 2 telnet sessions: Open a telnet session into port 2030 Login with your last name (/login kriens) Open a second telnet session into port 2030 Login with another name (/login peter) Don’t forget, the first word is the name of the

receiverpeter Hello!

See if you can send messages.

Check the services in the console, and see that two channel services are registered

osgi> services (objectclass=*Channel)

Page 79: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

79 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

How services are designed

The Whiteboard pattern

Developed a simple Telnet Chat application

Chat sessions use the whiteboard approach to communicate with Channel services

Build a real, albeit small, bundle

Threading issues with bundles

Page 80: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

80 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section VIII – Service Tracking

Page 81: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

81 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Creating a Chat Library Bundle

The aQute.tutorial.telnetchat bundle contains code that must be repeated between different clients

A chat middleware library that captures the shared code would be useful. As a bundle, this could run on phones, Eclipse, vehicles, etc.

Add to the aQute.tutorial.chat project a new package: aQute.tutorial.chat

For this example, we create a Chat class that works on a command line basis

The Chat class will be added to the <myname>.chat bundle (we use aQute.tutorial.chat)

Lines that start with /are treated as commands

This bundle will therefore act as a middleware library and is the exporter of the chat package

Not all code is shown, however, this is available in the aQute.tutorial.chat project

Export-Package: aQute.tutorial.chat, \ aQute.service.channel

aQute.tutorial.chat

aQute.service.channel

aQute.tutorial.chat

aQute.tutorial.chat

aQute.tutorial.telnetchat

aQute.service.channel

aQute.tutorial.chat

aQute.tutorial.telnetchat

Page 82: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

82 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker

Finding services for each message is kind of expensive.

The ServiceTracker in org.osgi.util.tracker package with the Service Tracker class is intended to simplify this task

A Service Tracker maintains a list of services based on: A filter A specific class A Service Reference object

It reports any existing or new services as well as any services that become unregistered

Object addingService

void modifiedService

void removedService

The Service Tracker is used to track Channel services and store them in a Map object

Page 83: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

83 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker: create

Framework BundleA

BundleB

BundleC

Page 84: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

84 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker: open

Object addingService(ServiceReference r){…}

Framework BundleA

BundleB

BundleC

addServiceListener

Object addingService(ServiceReference r){…}

Page 85: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

85 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker: adding

Framework BundleA

BundleB

BundleC

addServiceListener

Object addingService(ServiceReference r){…}

Page 86: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

86 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker: removing

Framework BundleA

BundleB

BundleC

addServiceListener

void removedService(ServiceReference r,Objecto){…}

Page 87: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

87 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: The Case for the ServiceTracker: modified

Framework

BundleB

BundleC

addServiceListener

void modifiedService(ServiceReference r, Object o){…}

BundleA

Page 88: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

88 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Chat Library: Constructor

The Chat constructor initializes some fields and creates the Service Tracker

The user is given as a Channel service. The user of the Chat library must implement the Channel service to get a callback for any incoming messages.

public Chat(BundleContext context, final Channel user) { this.user = user; this.cntxt = context; channels = new ChannelTracker(context); channels.open();}

Chat.java

Page 89: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

89 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: Channel Tracker

The Channel Tracker is used to track Channel services

The addingService method gets the Channel service and puts the Channel in a Map under the given name

The removedService method just cleans up the Map by removing the Channel service

class ChannelTracker extends ServiceTracker { ChannelTracker(BundleContext context) { super(context, Channel.class.getName(), null); } public Object addingService( ServiceReference ref) { Channel buddy = (Channel) super .addingService(ref); String name = (String) ref .getProperty(Channel.CH_NAME); bdds.put(name, buddy); return buddy; } public void removedService( ServiceReference ref, Object buddy) { bdds.entrySet().remove(buddy); }}

Chat.java

Page 90: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

90 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: Logging in

The login method registers a new Channel service

The password is ignored

The result is sent as a message to the user

public void login(String name, String password) throws IOException { if (registration != null) registration.unregister(); registration = null; this.name = name; Hashtable properties = new Hashtable(); properties.put(Constants.SERVICE_PID, "pid:chat[" + InetAddress.getLocalHost() + "]:" + name); properties.put(Channel.CH_NAME, name); properties.put("remote", "*"); registration = cntxt.registerService( Channel.class.getName(), user, properties); user.send("", "Logged in as " + name);}

Chat.java

Page 91: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

91 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: execute

The execute method looks at the command line and scans for ‘/’ characters, which are commands

/help – Show short help

/buddies – List the buddies

/login – Login

/<buddy> to send to a buddy

If no / is given the message is sent to the last used buddy (if exists)

The last buddy is remembered in lastTo

public void execute(String line) throws IOException { if (!line.startsWith("/")) send(line); else { line = line.trim(); StringTokenizer st = new StringTokenizer( line, " \t"); int cnt = st.countTokens(); if (cnt != 0) { String ws[] = new String[cnt]; for (int i = 0; i < cnt; i++) { ws[i] = st.nextToken(); } if ("/ip".startsWith(ws[0])) doIP(); else if ("/buddies" .startsWith(ws[0])) doBuddies(); else if ("/help".startsWith(ws[0])) doHelp(); else if ("/login".startsWith(ws[0])) login(ws[1], null); else { lastTo = ws[0].substring(1); send(line .substring(ws[0].length()));}}}}

Chat.java

Page 92: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

92 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: send

The send method must transfer the message to the lastTo buddy.

We maintain all the buddy Channel services in the bdds Map field, so it is easy to find them

void send(String line) throws IOException { if (lastTo == null) user.send("", "No buddy"); else { Channel channel = (Channel) bdds .get(lastTo); if (channel != null) { channel.send(name, line); user.send(name, line); } else user.send("?", "Can't find " + lastTo); }}

Chat.java

Page 93: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

93 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: doBuddies, getBuddies

The doBuddies method sends the list of currently logged in buddies to the user

The getBuddies method returns the buddies as a String[]

void doBuddies() throws IOException { StringBuffer sb = new StringBuffer(); String del = ""; for (Iterator i = bdds.keySet() .iterator(); i.hasNext();) { sb.append(del); sb.append(i.next()); del = ", "; } user.send("", sb.toString()); } public synchronized String[] getBuddies() { return (String[]) bdds.keySet().toArray( new String[0]); }

Chat.java

Page 94: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

94 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

The Chat Library: utiltities

The doHelp method sends some help text to the user

The getName method returns the currently logged name

The close method uses a careful way to unregister the associated Channel service only once

Often it is not easy to control how many time close is called

void doHelp() throws IOException { user.send("", "You are logged in as: " + name); user.send( "", "/buddies List current online buddies"); user.send("", "/help - This message"); user.send("", "/login <id> - Login under id"); user.send("", "/<name> ... - Send msg to buddy"); user.send("", "... - Send msg to last used buddy");} public void close() { ServiceRegistration reg; synchronized (this) { reg = registration; if (reg == null) return; registration = null; } reg.unregister(); } public String getName() { return name; }

Chat.java

Page 95: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

95 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn

How to track services and react appropriately on their arrival and departure

How to use the Service Tracker to simplify this

The whiteboard pattern as a solution to many dynamic problems

Page 96: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

96 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section IX – Finishing Touch

Page 97: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

97 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Using the Chat Library with a Window

We now have a library bundle that is easy to use

We could adapt the aQute.tutorial.telnetchat

project, but that is old news

Lets make a small Swing program that shows a simple chat window

Call this project <myname>.chatwindow

Such a program is provided in the aQute.tutorial.chatwindow project

Export-Package: \ aQute.tutorial.chatwindowService-Component: \ aQute.tutorial.chatwindow.ChatWindow

aQute.tutorial.chatwindow

Page 98: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

98 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Using the Chat Library

The activate method creates a new Chat instance from the Chat library

We run the frame in the Swing thread so we do not have multithreading issues (see invokeAndWait)

The deactivate method sets a quit flag

protected void activate( ComponentContext context) throws Exception { this.chat = new Chat(context .getBundleContext(), this); SwingUtilities.invokeAndWait(this);}protected void deactivate( ComponentContext context) throws Exception { chat.close(); frame.setVisible(false); frame.dispose();}

ChatWindow.java

Page 99: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

99 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Using the Chat Library

The run method creates and opens a new window

Reads quit flag to determine when to close the application

The usual window verbosity …

The window creates:

A Frame (the window itself),

A text field that will contain the chat output, and

A line field that will contain the chat input

The rest of the processing is handled via the Key Listener

public void run() { frame = new JFrame("ChatWindow"); text = new JTextArea(); text.setEnabled(false); JScrollPane scroll = new JScrollPane( text); frame.getContentPane().add(scroll, BorderLayout.CENTER); line = new JTextField(); frame.getContentPane().add(line, BorderLayout.SOUTH); frame.setSize(400, 500); frame.setVisible(true); line.addKeyListener(this);}

ChatWindow.java

Page 100: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

100 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Using the Chat Library

The keyTyped method of the Key Listener interface processes when the new line is entered

The error method displays an error to the user

The send method displays a message to the user from another client

It is called via the Channel service that this Chat instance registered

private void error(Exception e) { text.append("error> "); text.append(e + ""); } public void send(final String from, final String string) { text.append(from + "> " + string + "\r\n"); } public void keyTyped(KeyEvent e) { try { if (e.getKeyChar() == '\r' || e.getKeyChar() == '\n') { String txt = line.getText(); chat.execute(txt.trim()); line.setText(""); } } catch (Exception ee) { error(ee); } } public void keyPressed(KeyEvent e) {} public void keyReleased(KeyEvent e) {}

ChatWindow.java

Page 101: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

101 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Running the Chat Window

Run the aQute.tutorial.chatwindow in the normal way

Voila!

Notice that this collaborates with the aQute.tutorial.telnetchat bundle.

Page 102: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

102 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What Did We Learn?

That the OSGi Service Registry is a surprisingly powerful model for collaboration

The decoupling that it promotes allows additional functionality without influencing existing functions

Page 103: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

103 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section X – Remoting

Page 104: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

104 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Remoting

The chat is kind of boring because it only works on our own laptop. Missing is discovery of each other’s bundles! Rescue is on the way …

Enable the aQute.tutorial.remoting project

This project can export services to other participating machines

The only requirement is that you have a property remote=* on your service. See code

The aQute.tutorial.remoting project will then export this service to any participating machine. Our Channel objects will therefore be spread all over the place

Build the aQute.tutorial.remoting bundle, copy to work, and test with your buddies.

public void login(String name, String password) throws IOException { if (registration != null) registration.unregister(); registration = null; this.name = name; Hashtable properties = new Hashtable(); properties.put(Constants.SERVICE_PID, "pid:chat[" + InetAddress.getLocalHost() + "]:" + name); properties.put(Channel.CH_NAME, name); properties.put("remote", "*"); registration = cntxt.registerService( Channel.class.getName(), user, properties); user.send("", "Logged in as " + name);}

Chat.java

Page 105: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

105 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Remoting

Machine A

Machine B

Machine E

Machine D

Machine C

network

Real Channel

Proxy of Channel

Broadcast +p2p

Page 106: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

106 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Section XI – Final

Page 107: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

107 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

What We Did Not Learn

Security Architecture

Permission Management

Signed Bundles

Package Management

Bundle Life Cycle Management

Configuration Management and Preferences

Servlet Support/Web Server

Device Access

Event Manager

UPnP

User Admin

Wire Admin

Application Model

Deployment Admin and Autoconf

Device Management Tree

Initial Provisioning

Position, Measurement, State

MetaType

And much, much, more

Page 108: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

108 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

Conclusion

The OSGi R4 Specifications consists of considerable more details than elucidated in this tutorial

There are many independent OSGi implementations on the market, both commercial and open source

Apache Felix, Atinav, Eclipse Equinox, Espial, IBM SMF, Knopflerfish/Ubiserv of Gatespace, ProSyst, …

The OSGi specification are today running on mobile phones, PDAs, embedded computers, desktops, and mainframes

Both in managed and unmanaged configurations

The OSGi specifications solve real world problems

The OSGi Alliance is working on making the OSGi specifications the standard for portable applications. Join us!

Page 109: OSGi Component Programming | OOPSLA 2006 © 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0 3 Copyright is held by the OSGi Alliance,

109

© 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OOPSLA 2006 Portland

© 2006 by IBM, aQute & OSGi Alliance; made available under the EPL v1.0

OOPSLA 2006 Portland

The End

Further reading:

http://www.osgi.org

http://bundles.osgi.org

http://www.eclipse.org/osgi

http://www.aqute.biz

http://www.ProSyst.com