Programming with Equinox The OSGi foundation for

Jeff McAffer, IBM Rational Tom Watson, IBM Lotus

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

ƒ Setup ƒ Introduction to OSGi ƒ Managing your Target Environment ƒ The Equinox/OSGi Development Model ƒ OSGi Basics ƒ Components ƒ Services ƒ Remoting ƒ Conclusion

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

ƒ You need to have the following software installed on your machine in a new workspace: ƒ Eclipse SDK 3.2 (http://eclipse.org) ƒ The tutorial projects from CVS: ƒ Server: bundles.osgi.org ƒ Repository /cvshome/bundles ƒ User apachecon ƒ Password 2006 ƒ Projects Select all projects under Tutorial

2 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Loading the tutorial projects from CVS

ƒ Window > Open Perspective > Other > CVS Repository Exploring ƒ In CVS Repository view context menu: New > Repository Location ƒFill in the necessary CVS Repository information ƒ In CVS Repositories view, expand: HEAD/Tutorial ƒ Select all projects under Tutorial and choose Check Out

3 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Your Workspace (more or less)

4 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section I - OSGi Background

5 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What is the OSGi service platform?

ƒ A JavaTM framework for developing remotely deployed service applications, that require: ƒ Reliability ƒ Large scale distribution ƒ Wide range of devices ƒ Collaborative ƒ Created through collaboration of industry leaders ƒ Spec 4.0 publicly available at www.osgi.org … ƒ The Dynamic Modularity Layer for Java! ƒ Cool!

6 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Why the OSGi Service Platform?

ƒ What problems does the OSGi Service Platform address? ƒ A unified software market:

ƒ 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 software and hardware ƒ Managing the software life-cycle

7 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 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 ƒ LinuxTM is nice, but it is sub-optimal for smaller devices ƒ Benefits of the OSGi Platform ƒ Applications run unmodified on different hardware and software architectures

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

ƒ A DVD player can contain 1 Million lines of code ƒ Comparison: Space Shuttle ~ 0.5 Million ƒ A BMW car can contain up to 50 networked computerized devices ƒ Eclipse contains 2.5 million lines of code ƒ An average programmer writes an average of 10 lines a day … ƒ Houston … we have a problem

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

Service Oriented Programming

Productivity Structured Programming

Assembly

Complexity and Size

10 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Limits 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

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

ƒ Separate the contract from the implementation ƒ Allows alternate implementations ƒ Dynamically discover and bind available implementations Service Contract ƒ Based on contract (interface) provides ƒ Components are reusable Component ƒ Not coupled to implementation details uses

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

Application ƒ Allows applications to share a The ApplicationApplication single Java VM ApplicationApplication BlueApplication-Application Speech XML USB ƒ Classloading toothApplication OSGi Library ƒ Isolation/Security OSGi Web OSGiJTAPI 3D Math ƒ Communication `& OSGi The ApplicationServer Java Collaborations between JavaCommJavaVM Mail VM Security TCP/IP applications System ClassVMPorts Libraries Java Media Distri- ƒ Life cycle management Imaging JavaJavaVM SQL FW buted ƒ Policy free JavaVMVM Crypto- VMOperating SystemDirec- UPnP GUI ƒ Policies are provided by graphyOperatingOperating System Systemtories bundles Operating SystemJava JavaVM ƒ API is fully self managed VM Operating System Operating System

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

Services

Life Cycle Security

Applications Module

Execution Environment

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

ƒ OSGi only use a subset of J2SE and J2ME CDC ƒOSGi Minimum EE CLDC/ ƒ Matches most profiles MIDP ƒ Implementations can use more than the OSGi Minimum EE ƒ Security is not mandatory ƒ CLDC is possible if class loaders OSGi are added in a device specific Min. way J2SE CDC/FP

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

ƒ Packaging of applications and libraries in Bundles ƒRaw Java has significant deployment issues bundle ƒ Class Loading modularization bundle ƒRaw Java provides the Class Path as an ordered search list, which makes it hard to control multiple applications bundle ƒ Protection bundle ƒRaw Java can not protect certain bundle packages and classes ƒ Versioning ƒRaw Java can not handle multiple versions of the same package bundle bundle

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

ƒ System Bundle represents the OSGi Framework ƒ Provides an API for managing System bundle bundles bundle M ƒInstall ƒResolve Bundle ƒStart X-v2X ƒStop ƒRefresh ƒUpdate Bundle Bundle B ƒUninstall A ƒ Based on the module layer

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

ƒ Bundle is started by the Bundle Activator class ƒ Header in Manifest refers to this class ƒ Interface has 2 methods INSTALLED STARTING ƒStart: Initialize and return immediate ƒStop: Cleanup start ƒ The Activator gets a Bundle Context that provides access to the RESOLVED ACTIVE Framework functions ƒ Framework provides Start Level stop service to control the start/stop of groups of applications UNINSTALLED STOPPING

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

ƒ Provides an in-VM service model ƒ Discover (and get notified about) services based on their interface or properties ƒ Bind to one or more services by ƒ program control, ƒ default rules, or ƒ deployment configuration ƒ 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

19 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Planned R4 Evolution Application Manager MIDP Container Signed Bundles Declarative Services Power Management Device Management Security Policies

Mobile R3 UPnP Exporter Diagnostics/Monitoring UPnP Framework Layering Initial Provisioning Initial Provisioning Name Space UPnP … Start Level IO Connector Wire Admin XML Parser Measurement & State Position Execution Env. Vehicle PackageR2 Admin Configuration Admin Permission Admin User Admin Preferences MetaType R1 Service Tracker Framework Http Log

Home Automation Device Access 2000 2001 2003 2005

20 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Benefits of Using the OSGi Service Platform

ƒ Components are smaller ƒ Easier to make ƒ Components are not coupled to other components ƒ Gives reusability ƒ Excellent model for the myriad of customizations and variation that are required of today’s devices ƒ Collaborative model ƒ Allows reuse of other components for most problems

21 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section II – Equinox and Eclipse

22 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What is Equinox ?

ƒ An open source community focused on OSGi Technology ƒ http://www.eclipse.org/equinox/ ƒ Develop OSGi specification implementations ƒ Prototype ideas related to OSGi ƒ An OSGi Framework implementation ƒ Core of the Eclipse runtime ƒ Provides the base for Eclipse plug-in collaboration ƒ Fully compatible with the OSGi R4 specification ƒ New for Eclipse 3.2 – Other specification implementations ƒ Device Manager, Declarative Services, Event Admin, HTTP Service, Log Service, Metatype Service, Preferences Service, User Admin, Wire Admin – More on the way!!

23 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Equinox Target Environment Bundle A {} ƒ Eclipse makes it easy to develop for all OSGi Service Platforms Install ƒ A target platform ƒContains a set of bundles Bundle c Bundle B {} ƒDefines runtime parameters {} ƒ To Define the Target Platform, goto: Bundled ƒPreferences ->Plug-in Development - {} Bundle F >Target Platform {} BundleG Bundle E ƒSelect the target project in your {} {} workspace as location Target ƒ Advanced target management using OSGi Framework “Target Definitions” (New->Other->Plug- (Equinox) in Development->Target Definition)

24 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Setting up the Target Platform

25 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What Did We Learn

ƒ The OSGi Service Platform is kind of a Java Operating System ƒ It simplifies: ƒ Deployment Problems ƒ Software composition ƒ Software management ƒ Eclipse provides a development environment for OSGi Bundles ƒ Equinox provides open source implementations of the OSGi specifications in the Equinox project

26 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section III - Fundamental OSGi concepts

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

OSGi Framework

Bundle A {} Bundle B {}

Bundle C = service, java interface {}

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

ƒ A bundle is the deliverable application ƒ Like a WindowsTM 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

29 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What is in a Bundle?

ƒ A Bundle contains (normally in a JAR file): ƒ Manifest ƒ Code ƒ Resources Bundle A ƒ The Framework: {} ƒ Reads the bundle’s manifest ƒ Installs the code and resources ƒ Resolves dependencies ƒ During Runtime: ƒ Calls the Bundle Activator to start the bundle ƒ Manages java classpath ƒ Handles the service dependencies ƒ Calls the Bundle Activator to stop the bundle

30 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Create the Hello World bundle

Step 1. Create new plug-in project

Step 2 Project name: helloworld an OSGi framework: standard Step 3 Step 4 Generate an activator Use the Hello OSGi Bundle template

31 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Real code! Hello World (and Goodbye)

HelloWorld.java

ƒ The wizard has generated the package helloworld code on the left public class HelloWorld implements BundleActivator { ƒ This class implements the public void start( BundleActivator so that the BundleContext context) throws Exception{ Framework can start/stop the System.out.println( class "Hello world!!"); ƒ The activator is referenced in the } manifest public void stop( BundleContext context) throws Exception { System.out.println( "Goodbye world!!"); } }

32 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Real code! Hello World (and Goodbye)

ƒ The Manifest (in META- INF/MANIFEST.MF) is also META-INF/MANIFEST.MF generated by the wizard

ƒ Eclipse provides convenient editors Manifest-Version: 1.0 for the manifest Bundle-ManifestVersion: 2 Bundle-Name: Helloworld Plug-in ƒFor the source: click on Bundle-SymbolicName: helloworld MANIEST.MF Bundle-Version: 1.0.0 Bundle-Localization: plugin ƒ Notice: Bundle-Activator: ƒBundle-Activator (used to notify the helloworld.Activator Import-Package: bundle of lifecycle changes) org.osgi.framework;version="1.3.0" ƒImport-Package (dependencies)

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

ƒ The Launch Configuration is prepared for you ƒ Run -> Run … -> EclipseTutorial ƒ Deselect “Workspace Plug-ins” and “Target Platform” checkbox ƒ This removes all possible bundles from the launch configuration ƒ Select the helloworld bundle and Select “Add Required Plug-ins” ƒ This calculates from the dependency information, which bundles are required to run our helloworld example

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

35 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Run the Hello World bundle

ƒ Press Run ƒThe Framework is a console application ƒ The Framework now runs the helloworld example ƒSee the printed text ƒ It also runs a Framework console ƒEquinox specific ƒ Type “ss” (show status) ƒLook at the active bundles ƒNotice the number for the helloworld bundle. This is the bundle id. ƒ Type “stop

36 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Self-Hosting Bundle Projects JAR file layout

META-INF/MANIFEST.MF file:c;/… ƒ Normally, a bundle is packaged in a helloworld/HelloWorld.class JAR file ƒThe traditional edit-compile-debug cycle. ƒ Self-Hosting Allows for quick debugging of bundle code Target Platform ƒNo packaging steps ƒNo deployment steps ƒJust code/save/run Project Layout ƒ Some changes require update of the bundle in the Framework META-INF/MANIFEST.MF reference:file:C:/… .project ƒConsole: .classpath src/helloworld/HelloWorld.java update bin/helloworld/HelloWorld.class bin dir content automatically added to root Complied into bin directory, non java files copied

37 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Creating deployable bundles – how it works

ƒ The build.properties file specifies the content of the bundle jar ƒSpecifies the source and output folders of the build.properties different libraries source.. = src/ ƒsource.. – The source directory of the project. output.. = bin/ Used for compilation and resources. bin.includes = META-INF/,\ ƒoutput.. – The output directory where class . files and resources are copied to ƒbin.includes – What is included in the JAR from the project directory

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

ƒ Export the content of a project into a bundle jar ƒBundle jars can be installed across multiple OSGi Framework implementations ƒThe Deployable plug-ins and fragments wizard can be used to generate a bundle jar from a project. ƒFile -> Export -> Deployable plug-ins and fragments

39 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What Did We Learn

ƒ The unit of deployment of an OSGi Service Platform ƒ The Eclipse Target Environment ƒ How to launch an Equinox environment with a defined set of bundles ƒ How to start/stop bundles ƒ How the Equinox console works ƒ How the classpath is managed for self hosted bundles

40 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section IV – Component interaction and collaboration

41 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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

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

OSGi Framework

Service registry Bundle Bundle packages packages

JAVA

Operating System

Hardware

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

Java Application Manager

No management bundles Service Midlet, registry Midlet, No collaboration Xlet, Xlet, or or Applet packages Applet packages No package management (versions!)

JAVA

Operating System No native code

Hardware

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

ƒ Java applications consists of classes placed in packages q ƒ Java searches for a package or class in q-1.0 different jar files and directories p ƒ These are usually specified in the r CLASSPATH environment variable p ƒ An OSGi Framework is a network of class loaders. q q-2.0 ƒ Parameterized by the Manifest headers ƒ Any dependencies between bundles are resolved by the Framework ƒ It is possible to fetch bundles on demand ƒ Complicated – But an OSGi Framework makes it painless to use Bundle Wire Exported package Constraint Exported package

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

Framework org.osgi.framework org.osgi.service.http Bundle A Export org.osgi.service.log A resolved com..service.log com.ibm.j9 Import org.osgi.service.http javax.servlet.http

Bundle B B resolved Export ericsson.osgi javax.servlet javax.servlet.http org.osgi.service.log Import org.osgi.service.http

46 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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 use p ƒImports packages that are not used Import-Package q ƒ Import-Package creates a dependency on just a package r r ƒCreates less brittle bundles because of s substitutability ƒMore cumbersome to use (Tools!) ƒ In almost all cases, Import-Package is Require-Bundle recommended because it eases deployment and version migration r ƒ The specifications detail a number of additional problems with Require-Bundle

47 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Service Specifics discover bind register

ƒ A service is an object registered with the Framework by a bundle to be used by other bundles service ƒ The semantics and syntax of a service are specified in a Java interface ƒ A bundle can register a service. package org.osgi.service.log; ƒ A bundle can use a service (bind to) import org.osgi.framework.ServiceReference; public interface LogService { ƒ 1..1 public static final int LOG_ERROR= 1; ƒ 0..1 public static final int LOG_WARNING= 2; ƒ 0..n public static final int LOG_INFO= 3; ƒ A service can be discovered dynamically public static final int LOG_DEBUG= 4; ƒ Services can go away at any time! public void log(int level, String message); public void log(int level, String message, Throwable exception); public void log(ServiceReference sr, int level, String message); public void log(ServiceReference sr, int level, String message, Throwable exception); }

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

ƒ 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) ƒ Extensive notifications for service life cycles ƒ Services have a unique id ƒ Services require permission ƒ Under Operator control ƒ Services are associated with properties ƒ Query language to find appropriate service ƒ Bundles can update the properties

49 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Manipulating Services ServiceRegistration registerService( String clazz, Object service, ƒ The BundleContext provides the Dictionary properties) methods to manipulate the service ServiceReference[] registry getServiceReferences( ƒ Service registrations are handled by String clazz, String filter) ServiceRegistration objects ƒThey can be used to unregister a Object getService( service or modify its properties ServiceReference reference) ƒ Service References give access to boolean ungetService( the service as well as to the service’s ServiceReference reference); properties ƒ Access to service objects is through the getService method. These services should be returned with the ungetService method

50 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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 reduce the complexity for bundle developers ƒ Services provide a very powerful dynamic programming model

51 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section V – Service Components

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

META-INF/MANIFEST.MF

ƒ The dynamic nature of services make Manifest-Version: 1.0 … programming more complicated Import-Package: org.osgi.framework;version, ƒ The declarative service model simplifies org.osgi.service.component, handling these dynamics org.osgi.service.log ƒDependencies are defined in an XML file Service-Component: ƒ Declarative Services: OSGI-INF/component.xml ƒOptionally Depend on one or more services ƒOptionally Provide a service ƒOptionally lazy initialized ƒConfigurable OSGI-INF/component.xml ƒ Example shows a hello world bundle that logs Hello and Goodbye ƒ First add dependencies by selecting ƒAdd the component and log package

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

Step 1 – Add new Imported Packages

Step 2 – Select the necessary packages

Step 3 – Save the bundle manifest

54 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Login Component Source Code OSGI-INF/component.xml ƒ A component can be any class called when the component is activated/deactivated ƒDependencies must be resolved: Log Service ƒ The ComponentContext class provides access to the referenced services Component.java ƒThe locateService methods finds a reference package hello; import org.osgi.service.component.*; ƒ The component instance can be sure that import org.osgi.service.log.*; at any moment in time between activate public class Component { LogService log; and deactivate there is a valid Log Service protected void activate(ComponentContext context){ log = (LogService) context.locateService("LOG"); log.log(LogService.LOG_INFO, "Hello World"); } protected void deactivate(ComponentContext context){ log.log(LogService.LOG_INFO, "Goodbye World"); }}

55 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Add Declarative Services, Log, and Component

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

ƒ Launch the EquinoxTutorial launch configuration ƒ You can look in the log with the log command ƒLast event is at bottom ƒ Stop the bundle ƒStop ƒ Run log again

57 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What Did We Learn

ƒ Programming with services is complicated ƒ The Declarative Services model makes service programming much simpler ƒ How the component XML is constructed ƒ We used the Log Service

58 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section VI – Use Case: Developing a Chat Service

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

ƒ We will now design a service that simplifies Chat/Instant Messaging clients SWT Chat Telnet ƒWe do the clients later, this is just intended to Chat Service Chat support clients. Output ƒ A Chat client should be able to Input channel communicate with a user through: channel ƒA window, telnet session, MSN, AOL, Skype, etc. interface. Window Channel service Telnet Chat send(from,msg) ƒ We base the communication between chat Connections clients on a Channel interface. ƒWe register a service we receive messages from ƒThe registry contains other channel services we can send messages to ƒA property contains the user name Tom JeffJeff Tom ƒ For ease of use, we use a command sessions sessiosessionn sessions based interface for login and listing buddies Channel services

60 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Channel Service Design Channel.java package aQute.service.channel; import java.io.*; ƒ Create a new project to hold our service public interface Channel { interface String CH_NAME="channel.name"; ƒCall this project .chat void send(String from, String msg) ƒThis is a Plug-in Project throws IOException; } ƒ The Channel service is one way: ƒEach channel service represents on user ƒWe only receive through a channel service ƒA client uses a channel service to send a message to a specific user META-INF/MANIFEST.MF ƒ The CH_NAME service property Manifest-Version: 1.0 ƒThis property must be registered with the Bundle-ManifestVersion: 2 service Bundle-Name: Chat Plug-in Bundle-SymbolicName: aQute.chat ƒThe value is the name of the user, e.g. tom Bundle-Version: 1.0.0 ƒ A single method send with the following Bundle-Localization: plugin Import-Package: arguments org.osgi.framework;version="1.3.0" ƒfrom – The user name that sends the Export-Package: aQute.service.channel message ƒmsg – The message to be send ƒ Export the service channel package

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

Bundle C Bundle B Bundle A { } { } { } ƒ The Channel Service uses the White Board Approach ƒ The White Board approach is: ƒEach Event Listeners (Channels) are register registered as Services ƒAny interested client uses the service to send events (messages) to Registry ƒ It is an effective approach to reduce the Publisher number of couplings between bundles Events: register, ƒ There is a white-paper comparing a unregister, whiteboard approach with a non modified whiteboard approach.

get

Server bundle

62 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Telnet Based Chat Client

Thread ƒ The best way to start is to design a small Thread test program. Activated by Declarative Services ƒ The easiest way to a “UI” is a telnet server that uses the Channel service to communicate with siblings ƒThis also shows how Internet servers should TelnetChat LogServiceLogService TelnetChat be constructed ƒ The telnet Chat server will create a 1 Handler for each opened session. For each session * ƒThe Handler is a thread that waits for input from the user User ƒThe Handler registers a Channel. HandlerHandler ƒ The Handler is stopped when the session closes. ƒThis unregisters the Channel service

ChannelChannel

63 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The TelnetChat Manifest and component.xml

META-INF/MANIFEST.MF ƒ Create a new project for a telnet chat Manifest-Version: 1.0 Bundle-ManifestVersion: 2 ƒ Call this project .telnetchat Bundle-Name: Telnetchat Plug-in ƒ This is a Plug-in Project Bundle-SymbolicName: aQute.telnetchat Bundle-Version: 1.0.0 ƒ Define the manifest and component Bundle-Localization: plugin Service-Component: OSGI-INF/component.xml definition Import-Package: aQute.chat, ƒ Add the package import dependencies to aQute.service.channel, org.osgi.framework;version="1.3.0", the manifest. Either org.osgi.service.component, ƒ Direct in the source code org.osgi.service.log ƒ Via the Dependencies tab ƒ Add the reference to the component.xml ƒ The component.xml must reside in OSGI- INF OSGI-INF/component.xml ƒ We only specify a reference to the Log Service

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

TelnetChat.java ƒ The code does not show the import protected void activate( ComponentContext context) { this.context = context; packages and field definitions this.log = (LogService) ƒ The source code is provided for you to context.locateService("LOG"); further check in aQute.telnetchat start(); } ƒ Eclipse will tell you when they miss protected void deactivate(ComponentContext context) ƒ The activate method: throws Exception { ƒ Remembers the context for later quit = true; for (Iterator i = handlers.iterator(); i.hasNext();) ƒ Gets the log service try { ƒ Starts the thread. Handler h = (Handler)i.next(); h.close(); ƒ The deactivate method: } catch (Throwable e) { ƒ Sets the quit flag so any loops in the started // We are closing Thread will finally end } server.close(); ƒ Closes all created Handlers } ƒ Exceptions are ignored because we are closing ƒ And closes the server socket object, this will surely quit the main socket accept loop.

65 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The TelnetChat run method

TelnetChat.java

ƒ The run method creates a socket and public void run() { while (!quit) try { accepts incoming connections. server = new ServerSocket(2030); ƒ For bundles, it is crucial that this loop server.setSoTimeout(1000); never quits, but also not overloads the loop(); } catch (Exception e) { system log.log(LogService.LOG_ERROR, ƒ There is usually no end user watching a "[TelnetChat] Inner loop", e); server … sleep(10000); } ƒ The outer loop therefore catches errors, } sleeps and try again ƒ A lot of problems disappear over time. For void loop() throws Exception { example, an Internet connection can be while (!quit) try { temporarily be down Socket socket = server.accept(); Handler handler = new Handler( ƒ The socket has a timeout to check the flag context.getBundleContext(), socket, this); regularly handlers.add(handler); handler.start(); ƒ The inner loop } catch (SocketTimeoutException e) { ƒ Wait for an incoming socket // Just for checking the quit flag ƒ Creates a handler // at a regular basis } ƒ And starts the handler’s thread }

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

TelnetChat.java void remove(Handler handler) { ƒ Convenience methods handlers.remove(handler); }

void sleep(int ms) { try { Thread.sleep(ms); } catch (InterruptedException e1) {} }

67 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Handler Source Code

Handler.java public Handler(BundleContext context, Socket ƒ The constructor receives the socket socket, TelnetChat activator) throws Exception { for the session with the end user. It this.ctxt = context; this.socket = socket; initializes: this.parent = activator; writer = new PrintWriter( ƒThe fields new OutputStreamWriter(socket.getOutputStream())); } ƒA Writer object to send text to the end public void send(String source, user String msg) throws IOException { writer.println(source + "> " + msg); ƒ The send method writes the writer.flush(); } message in the Write object and void close() { flushes it to ensure the user sees it try { quit = true; ƒ The close method closes the different writer.close(); socket.close(); objects and quits the main loop: } catch (IOException e) { ƒBy setting the quit flag // Ignore in close } ƒBy closing the socket }

68 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Handler Source Code

Handler.java public void run() { ƒ The run() method loops as long as writer.println("Welcome … Chat"); writer.print("Enter name: "); there is input from the user. It quits writer.flush(); when the socket is closed or an error try { BufferedReader rdr = occurs. new BufferedReader( new InputStreamReader( ƒ Errors are only logged when the socket.getInputStream())); while (!quit && (line=rdr.readLine()) != null) { session has not quit because there line = line.trim(); are usually socket errors during process(line); } closing } catch (Exception e) { if (!quit) ƒ The finally clause is used to parent.log.log( LogService.LOG_ERROR, guarantee that the handler is "reading user input", e); removed from the parent when it is } finally { if (channel != null) closed. channel.unregister(); parent.remove(this); ƒ If a valid line is received, it is send to parent = null; close(); the process method } }

69 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Handler Source Code

Handler.java void process(String line) throws IOException, ƒ The process method handles a Exception { if (user == null) { line of input from the user user = line; Hashtable props = new Hashtable(); ƒ If we did not have a login name props.put(Channel.CH_NAME, user); channel =ctxt.registerService( yet, we assume it is the given Channel.class.getName(), this, props); send("info", "User set to: " + user); line } else { if (line.startsWith("/quit")) ƒ If the line starts with /quit, we quit writer.println("bye "); else the program dispatch(line); } ƒ Otherwise we assume it is a line } we need to send to another user, which is handled in the dispatch method

70 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Handler Source Code

Handler.java void dispatch(String line) throws Exception { ƒ The dispatch method parses the String parts[] = line.split("\\W"); destination name from the input ServiceReference channels[] = ctxt.getServiceReferences( ƒ For this name , finds a Channel Channel.class.getName(), "(" + Channel.CH_NAME + "=" + parts[0] + ")"); service if (channels != null) { Channel to = (Channel)ctxt.getService(channels[0]); ƒ It then sends the remainder of to.send(user, line.substring(parts[0].length())); ctxt.ungetService(channels[0]); the line to that service } else { send("error", "no such user: " + parts[0]); } }

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

ƒ Launch the EquinoxTutorial ƒ Do not forget to check the launch configuration ƒ The TelnetChat bundle included? ƒ Includes all required bundles from the Target environment? ƒ Do not forget to start the bundle via the console ƒ Create 2 telnet sessions: ƒ Open a telnet session into port 2030 ƒ Login with your last name ƒ Open a second telnet session into port 2030 ƒ Login with another name ƒ See if you can send messages Check the services, and see that two channel services are registered ƒ Services (objectclass=*Channel)

72 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What Did We Learn

ƒ How services are designed ƒ White board approach ƒ Developed a simple telnet chat application ƒ Chat sessions use the white board approach to find Channel services ƒ The Channel service is used to send messages

73 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section VII – Service Tracking

74 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Finishing the Chat Service Chat.java Chat(BundleContext cntxt,Channel user); ƒ The TelnetChat contains code that must be repeated between different clients void execute(String ln) throws IOException; ƒ A Chat library that captures the shared String[] getBuddies(); code would be useful ƒ As a bundle, this could run on phones, void close(); Eclipse, etc. String getName(); ƒ For this example, we create a Chat class void login( String user, String passwd); that works on a command line basis ƒ The Chat class will be added to the .chat bundle ƒ /xxx are commands META-INF/MANIFEST.MF ƒ This bundle will therefore act as a library Manifest-Version: 1.0 and exports the chat package Bundle-ManifestVersion: 2 Bundle-Name: Chat Plug-in ƒ Not all code is shown, however, this is Bundle-SymbolicName: aQute.chat available in the aQute.chat project Bundle-Version: 1.0.0 Bundle-Localization: plugin Import-Package: org.osgi.framework;version="1.3.0" Export-Package: aQute.service.channel, aQute.chat

75 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Case for the ServiceTracker

ƒ Finding services for each message is kind of expensive. ƒ The ServiceTracker in org.osgi.util.tracker package is intended to simplify this task ƒ A service tracker maintains a list of services based on: ƒ A filter ƒ A specific class ƒ 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 channels and store them in a Map

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

Framework Bundle A

Bundle B

Bundle C

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

ServiceTracker Framework Bundle addServiceListener A

Bundle B

Bundle C Object addingService(ServiceReference r){…}

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

ServiceTracker Framework Bundle ServiceListener A

Bundle B

Bundle C Object addingService(ServiceReference r){…}

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

ServiceTracker Framework Bundle ServiceListener A

Bundle B

Bundle C void removedService(ServiceReference r,Objecto){…}

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

Framework Bundle ServiceListener A

Bundle B

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

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

Chat.java public Chat(BundleContext context, final ƒ The Constructor initializes some Channel user) { fields and creates the service this.user = user; this.cntxt = context; tracker channels = doChannelTracker(context, user); channels.open(); ƒ The user is given as a Channel. } The user of this library must implement this service to get a callback with any incoming messages.

82 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Chat Library Service Tracker

Chat.java ServiceTracker doChannelTracker( ƒ The Service Tracker is used to BundleContext cntxt, final Channel user) { track Channel services return new ServiceTracker( cntxt, ƒ The addingService method gets Channel.class.getName(), null) { public Object addingService(ServiceReference ref) { the Channel and puts the Channel buddy = (Channel)context.getService(ref); if (buddy != user) { Channel in a Map under the String name = given name (String)ref.getProperty(Channel.CH_NAME); String rn = name; int n = 0; ƒ The removedService method synchronized (bdds) { just cleans up the Map when a while(bdds.containsKey(rn)) rn = name + "-" + n++; Channel service is removed bdds.put(rn, buddy); } } return buddy; }

public void removedService( ServiceReference ref,Object buddy){ bdds.remove(ref.getProperty(Channel.CH_NAME)); } }); }

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

Chat.java public void login(String name, ƒ The login method registers a new String password) throws IOException { Channel service if (registration != null) registration.unregister(); ƒ The password is ignored registration = null; this.name = name; ƒ The result is sent as a message Hashtable properties = new Hashtable(); properties.put( to the user Constants.SERVICE_PID, "pid:chat[" + InetAddress.getLocalHost() + "]:" + name); properties.put(Channel.CH_NAME, name); registration = cntxt.registerService( Channel.class.getName(), user, properties); user.send("", "Logged in as " + name); }

84 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Chat Library: execute

Chat.java public void execute(String line) throws IOException { ƒ The execute method looks at the if (!line.startsWith("/")) command line and scans for ‘/’ send(line); else { characters, which are commands String ws[]=line.split("\\s+"); if ("/buddies".startsWith(ws[0])) ƒ/help – Show short help doBuddies(); else if("/help".startsWith(ws[0])) doHelp(); ƒ/buddies – List the buddies else if("/login".startsWith(ws[0])) login(ws[1], null); ƒ/login – Login else { lastTo = ws[0].substring(1); ƒ/ to send to a buddy send(line.substring(ws[0].length() + 1)); } ƒ If no / is given the message is } sent to the last used buddy }

85 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Chat Library: send

Chat.java void send(String line) throws IOException { ƒ The send method must transfer if (lastTo == null) the message to the lastTo buddy. user.send("", "No buddy"); else { ƒ We maintain all the buddy Channel channel = (Channel) bdds.get(lastTo); if (channel != null) { Channel services in the bdds channel.send(name, line); user.send(name, line); Map field, so it is easy to find } else user.send("?", "Can't find " + lastTo); them } }

86 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Chat Library: doBuddies, getBuddies

Chat.java void doBuddies() throws IOException { ƒ The doBuddies method sends StringBuffer sb = new StringBuffer(); the list of currently logged in String del = ""; for(Iterator i = buddies to the user bdds.keySet().iterator(); i.hasNext();) { ƒ The getBuddies method returns sb.append(del); sb.append(i.next()); the buddies as a String[] del = ", "; } user.send("", sb.toString()); }

public synchronized String[] getBuddies() { return (String[]) bdds.keySet().toArray(new String[0]); }

87 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 The Chat Library: utiltities Chat.java void doHelp() throws IOException { user.send("", "…n as: " + name); user.send("", "/bdds …"); ƒ The doHelp method sends some user.send("", "/help …"); user.send("", "/login …"); help text to the user user.send("", "/ … "); user.send("", "…"); ƒ The getName method returns the }

currently logged name public String getName() { ƒ The close method uses a careful return name; } way to unregister the associated public void close() { Channel service only once ServiceRegistration reg; synchronized (this) { ƒOften it is not easy to control how reg = registration; if (reg == null) many time close is called return; registration = null; } reg.unregister(); }

88 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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 ƒ The white board pattern as a solution to many dynamic problems

89 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Section VIII – Finishing Touch

90 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Using the Chat Library META-INF/MANIFEST.MF Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Swtchat Plug-in Bundle-SymbolicName: aQute.swtchat ƒ We now have a library bundle that is easy Bundle-Version: 1.0.0 Service-Component: to use OSGI-INF/component.xml ƒ We could adapt the Telnet Chat, but that is Bundle-Localization: plugin Import-Package: aQute.chat, old news aQute.service.channel, org.eclipse.swt, ƒ Lets make a small SWT program that org.eclipse.swt.events, org.eclipse.swt.layout, shows a simple chat window org.eclipse.swt.widgets, ƒ Call this project .swtchat org.osgi.framework, org.osgi.service.component ƒ This is a Plug-in Project ƒ Such a program is provided in the aQute.swtchat bundle OSGI-INF/component.xml

91 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Using the Chat Library ChatWindow.java

protected void activate( ComponentContext context) ƒ The activate method creates a throws Exception { this.chat = new Chat( new Chat instance and starts the context.getBundleContext(), this); start(); thread } protected void deactivate( ƒ The deactivate method sets a ComponentContext context) throws Exception { quit flag and interrupts the quit = true; interrupt(); running thread so that it can exit } public void run() { ƒ The run method creates and createShell(); shell.open(); opens a new window display = shell.getDisplay(); while (!shell.isDisposed() && !quit) ƒReads quit flag to determine try { if (!display.readAndDispatch()) when to close the application display.sleep(); } catch (Exception e) { error(e);} if (!shell.isDisposed()) shell.dispose();chat.close(); }

92 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Using the Chat Library void createShell() { shell = new Shell(); shell.setText("SWT Chat"); GridLayout layout = new GridLayout(); ƒ The usual window verbosity … layout.numColumns = 1; shell.setSize(500, 300); ƒ The window creates: shell.setLayout(layout); text = new Text(shell, SWT.MULTI|SWT.BORDER|SWT.MULTI|SWT.V_SCROLL ƒA shell (the window itself), |SWT.READ_ONLY); GridData spec = new GridData(); ƒA text field that will contain the spec.horizontalAlignment = GridData.FILL; spec.grabExcessHorizontalSpace = true; chat output, and spec.verticalAlignment = GridData.FILL; spec.grabExcessVerticalSpace = true; ƒA line field that will contain the text.setLayoutData(spec); line = new Text(shell, chat input SWT.MULTI|SWT.BORDER|SWT.V_SCROLL); spec = new GridData(); spec.horizontalAlignment = GridData.FILL; spec.grabExcessHorizontalSpace = true; spec.verticalAlignment = GridData.FILL; spec.grabExcessVerticalSpace = false; spec.heightHint = 40; line.setLayoutData(spec); line.addKeyListener(this); }

93 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Using the Chat Library public void keyPressed(KeyEvent ev){} public void keyReleased(KeyEvent ev){ switch (ev.keyCode) { case SWT.CR : try { ƒ The keyReleased method String txt = line.getText(); chat.execute(txt.trim()); processes when the new line is line.setText(""); } catch (IOException e1) { entered error(e1); } ƒ The error method displays an break; } error to the user } ƒ The send method displays a void error(Exception e) { message to the user from if (!quit) { text.append("error> "); another client text.append(e + "");}}

public void send(String from, String str) { display.asyncExec(new Runnable() { public void run() { text.append(from + "> " + str + "\r\n"); } }); }

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

ƒ Run the SWT Chat in the normal way ƒVerify the target bundles

95 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 Remoting public void login(String name, String password) throws IOException{ if (registration != null) registration.unregister(); registration = null; ƒ The chat is kind of boring because it only this.name = name; works on our own laptop. Missing is Hashtable properties = discovery of each other’s bundles! Rescue new Hashtable(); is on the way … properties.put(“remote”, “*” ); ƒ Enable the aQute.remoting project properties.put( Constants.SERVICE_PID, ƒThis project can export services to other "pid:chat[“ + participating machines InetAddress.getLocalHost() ƒ The only requirement is that you have a + "]:" + name); properties.put( property remote=* on your service. See Channel.CH_NAME, name); code registration = cntxt.registerService( ƒ The aQute.remoting project will then Channel.class.getName(), user, properties); export this service to any participating user.send("", "Logged in as " machine + name); ƒ Our Channel objects will therefore be } spread all over the place ƒ Enable the aQute.remoting bundle, launch, and test with your buddies.

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

Machine A Machine C

Broadcast +p2p

network

Machine E

Machine D Proxy of Channel

Real Channel

97 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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

98 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; made available under the EPL v1.0 What We Did Not Learn

ƒ Security Architecture ƒ UPnP ƒ Permission Management ƒ User Admin ƒ Signed Bundles ƒ Wire Admin ƒ Package Management ƒ Application Model ƒ Bundle Life Cycle Management ƒ Deployment Admin and Autoconf ƒ Configuration Management and Preferences ƒ Device Management Tree ƒ Servlet Support/Web Server ƒ Initial Provisioning ƒ Device Access ƒ Position, Measurement, State ƒ Event Manager ƒ MetaType ƒ And much, much, more

99 OSGi Component Programming | © 2006 by IBM, aQute & OSGi; 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 ƒ , Atinav, Eclipse Equinox, Espial, IBM® SMF, Knopflerfish/Ubiserv of Gatespace, ProSyst, … ƒ The OSGi specifications are running today 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!

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

Further reading:

http://www.eclipse.org/equinox/ http://www.osgi.org http://bundles.osgi.org http://www.aqute.biz

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

ƒ IBM is a registered trademark of International Business Machines Corp. in the United States, other countries, or both. ƒ Java and all Java-based trademarks are trademarks of , Inc. in the United States, other countries, or both. ƒ Linux is a registered trademark of Linus Torvalds in the United States, other countries, or both. ƒ Microsoft, Windows, Windows NT, and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. ƒ Other company, product, or service names may be trademarks or service marks of others.

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