new cs5233 components – models and engineering · 2011. 6. 6. · seite 3 eclipse / rcp – hello...
TRANSCRIPT
CS5233Components – Models and Engineering(Komponententechnologien) Master of Science (Informatik)
OSGI – Bundles and Services
Prof. Dr. Th. Letschert
Seite 2
Bundles
Slides on OSGi are based on
– OSGi Alliance: OSGi Service Platform Core Specification OSGi 2009
– J. McAffer, P. Vanderlei, S. Archer: OSGi and Equinox, Addison-Wesley 2010
– Wütherich/Hartmann/Kolb/Lübken, Die OSGI Service Platform – Dpunkt Verlag, 2008
Seite 3
Eclipse / RCP – Hello World Bundle
Context– download and install Eclipse for RCP Developers
or install General Purpose Tools / Eclipse Plugin Development Environment
– RCP, Plugin, Bundle: RCP = Rich Client Platform Eclipse RCP
➢ Framework / platform / run-time for RCP applications➢ makes it easy to create rich client applications
RCP-Application = Application logic as plugin / bundle+ Eclipse-RCP run-time
Seite 4
Eclipse / RCP – Hello World Bundle
Example: Hello World BundleCreate a new Plug-in Project called “HelloWorld”
– Wizard page 1: target platform: choose OSGi / standard
target platform is about who will run the pluginOSGi means that it will run directly on an OSGi framework (not within eclipse)standard means do not use special Equinox-extension
– Wizard page 2: Execution environment is an OSGi concept, it denotes the minimum Java
runtime for the bundle, do not select anything choose generate Activator !
Activator is the activator for the bundle as specified by OSGi “A bundle is activated by calling its Bundle Activator object, if one exists. The BundleActivator interface defines methods that the Framework invokes when it starts and stops the bundle.” OSGi Core Specification, 4.2.1
The Activator must be declared in the manifest file with the headerBundle-Activator: <full qualified class name>
– Wizard page 3: do not select a template
Seite 5
Eclipse / RCP – Hello World Bundle
Created files: MAINIFEST.MF manifest fileActivator.java activator class template build.properties packaging / deployment configuration file
Seite 6
Eclipse / RCP – Hello World Bundle
Created files: MAINIFEST.MF manifest file
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: HelloWorldBundle-SymbolicName: HelloWorldBundle-Version: 1.0.0.qualifierBundle-Activator: helloworld.ActivatorImport-Package: org.osgi.framework;version="1.3.0" MANIFEST.MF
We are creating an OSGi-Bundle, this is its Manifest.
Seite 7
Eclipse / RCP – Hello World Bundle
Created files: Activator.java activator class template
Activator.java
package helloworld;
import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() { return context; }
/* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; }
/* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext bundleContext) throws Exception { Activator.context = null; }
}
OSGi Core Spec.
Seite 8
Eclipse / RCP – Hello World Bundle
Created files: build.properties packaging / deployment configuration file
build.properies
source.. = src/output.. = bin/bin.includes = META-INF/,\ .
build.properties, as seen by the build properties editor … and seen by a text editor
Seite 9
Eclipse / RCP – Hello World Bundle
fill the Activator with some code
Activator.java
package helloworld;
import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private static BundleContext context;
static BundleContext getContext() { return context; }
/* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) */ public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; System.out.println("Hello Bundle"); }
/* * (non-Javadoc) * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext bundleContext) throws Exception { Activator.context = null; System.out.println("Goodby world - the bundle stops."); }
}
Seite 10
Eclipse / RCP – Hello World Bundle
• run it in an OSGi framework
Run → Run as → OSGi Framework osgi> Hello Bundle. should appear in the console (after several exception messages)
• create a minimal run configuration
– run it: Run → Run as → OSGi Framework
– open the run configuration: Run → Run Configurations … / OSGi Framework
– edit the configuration rename it to HelloWorldConfig deselected everything besides
HelloWorldorg.eclipse.osgi
• export bundle
– Export → Deployable Plugins and Fragments
wizard next Page: select and name a directory / finish
Seite 11
Eclipse / RCP – Hello World Bundle
start OSGi console; install – start – stop – the plugin
generated bundle (jar file)with manifest
> java -jar /path/to/eclipse/plugins/org.eclipse.osgi_3.6.2.R36x_v20110210.jar -consoleosgi> install file:/path/to/my/plugins/HelloWorld_1.0.0.201005122137.jarBundle id is 1osgi> start 1Hello Bundleosgi> ssFramework is launched.
id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v201102101 ACTIVE HelloWorld_1.0.0.201005122137osgi> stop 1Goodby world - the bundle stops.osgi>
Seite 12
Eclipse / RCP – Hello World Bundle
Summary:
– Bundles are developed as Plugin projects in Eclipse
– Eclipse uses a directory structure for bundles that differs from the structure of the jar file
– By exporting the project Eclipse creates a bundle-jar
– The most simplistic bundle consists of a manifest file a class that implements org.osgi.framework.BundleActivator
– The activator has
a start method that gets called when the bundle is started a stop method that gets called when the bundle is stopped
For details of eclipse see:http://help.eclipse.org/helios/index.jsp
Seite 13
Bundle, Bundle Activator and Context
Activator:
– Activator:
manifest entry Bundle-Activator: <fully qualified class name> class that implements interface BundleActitivator
– If an activator class exists (and is named in the manifest file)
the bundle class loader will load the class and the framework will create an object of this type (using newInstance so it has to have a default constructor)
its start / stop methods will be called by the framework
– Methods of interface BundleActitivator
start(BundleContext)
Method to allocate resources, start threads, register services
Bundles must be stopped by the framework if this method throws an exception stop(BundleContext)
Method called if the bundle is stopped (except if it stopped via an exception thrown by start). Should be used to deallocate resources allocated by start, services do not have to be unregistered.
org.osgi.framework Interface BundleActivator
http://www.osgi.org/javadoc/r4v41/ OSGi™ Service Platform Release 4 Version 4.1
Seite 14
Bundle, Bundle Activator and Context
Activation Policy:
– Activation policy: How should a bundle be activated: eager or lazy
– Manifest entry Bundle-ActivationPolicy: lazy [ ; in/exclude directives]
– Eager activation (default)
bundle is activated when started
– Lazy activationbundle is not to be activated immediately when started, insteadactivation is to be deferred until at least one of its classes is loaded
– Include / exclude directives (optional with lazy activation)include: packages with classes that should trigger activationexclude: packages with classes that should not trigger activation
OSGi Core Spec.
Seite 15
Bundle, Bundle Activator and Context
Bundle Context:
– Bundle Context : Object of type BundleContext
– Proxy to the framework for a bundle
– Created when a bundle is started
– Passed as argument to the start method
– Can be used to:➢ Obtain information about the framework➢ Install new bundles➢ Interrogate other bundles➢ Obtain a persistent storage.➢ Retrieve service objects of registered services.➢ Register services.➢ Subscribe or unsubscribe to events.
org.osgi.framework Interface BundleContext
OSGi Core Spec.
Seite 16
Bundle, Bundle Activator and Context
Example : get information about bundles and framework
package helloworld;
import org.osgi.framework.Bundle;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.Constants;
public class Activator implements BundleActivator { . . . public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; System.out.println("All bundles:"); for (Bundle bundle: bundleContext.getBundles()) { System.out.print("Bundle: " + bundle + " state: " + bundle.getState()); if (bundle.getState() == 1) System.out.print(" UNINSTALLED "); if (bundle.getState() == 2) System.out.print(" INSTALLED "); if (bundle.getState() == 4) System.out.print(" RESOLVED "); if (bundle.getState() == 8) System.out.print(" STARTING "); if (bundle.getState() == 16) System.out.print(" STOPPING "); if (bundle.getState() == 32) System.out.print(" ACTIVE "); System.out.println(); } System.out.println("Framework Properties: "); System.out.println("Version: " + context.getProperty(Constants.FRAMEWORK_VERSION) ); System.out.println("Vendor: " + context.getProperty(Constants.FRAMEWORK_VENDOR) ); System.out.println("OS: " + context.getProperty(Constants.FRAMEWORK_OS_NAME) ); System.out.println("Processor: " + context.getProperty(Constants.FRAMEWORK_PROCESSOR) ); } . . . }
osgi> ssFramework is launched.id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v201102102 INSTALLED HelloWorld_1.0.0.201106061546osgi> start 2All bundles:Bundle: org.eclipse.osgi_3.6.2.R36x_v20110210 [0] state: 32 ACTIVE Bundle: HelloWorld_1.0.0.201106061546 [2] state: 8 STARTING Framework Properties: Version: 1.5.0Vendor: EclipseOS: LinuxProcessor: x86-64
Seite 17
Bundle: Activator and Context
Bundle
– Objects of type Bundle represent installed bundles
– Bundle objects may be used to:
➢ get information about the bundle
including the bundle's meta information
➢ manage the lifecycle of an installed bundle
➢ access a bundle's context
org.osgi.framework Interface Bundle
Seite 18
Bundle, Bundle Activator and Context
Example : List all headers of bundle with id 0
public void start(BundleContext bundleContext) throws Exception {Activator.context = bundleContext; Bundle bundle_0 = context.getBundle(0); System.out.println(bundle_0 + " with headers:"); @SuppressWarnings("unchecked") Enumeration<String> keys = bundle_0.getHeaders().keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); System.out.println(key + " \t" + bundle_0.getHeaders().get(key)); }}
org.eclipse.osgi_3.6.2.R36x_v20110210 [0] with headers:Manifest-Version 1.0Bundle-DocUrl http://www.eclipse.orgMain-Class org.eclipse.core.runtime.adaptor.EclipseStarterBundle-Localization systembundleBundle-RequiredExecutionEnvironment J2SE-1.5,OSGi/Minimum-1.2Bundle-SymbolicName org.eclipse.osgi; singleton:=true
...etc... the Mainfest headers
Manifest-Version: 1.0Bundle-DocUrl: http://www.eclipse.orgMain-Class: org.eclipse.core.runtime.adaptor.EclipseStarterBundle-Localization: systembundleBundle-RequiredExecutionEnvironment: J2SE-1.5,OSGi/Minimum-1.2Bundle-SymbolicName: org.eclipse.osgi; singleton:=true . . .
org.eclipse.osgi_3.6.2.R36x_v20110210.jar/meta-inf/MANIFEST
Seite 19
Bundle, Bundle Activator and Context
Example : install and start HelloWorld bundle
public void start(BundleContext context) throws Exception {System.out.println("The bundle loading bundle is starting");Bundle bundle = context.installBundle("file:/path/to/HelloWorld.jar");bundle.start();System.out.println(bundle + " with headers:");Enumeration<String> keys = bundle.getHeaders().keys();while (keys.hasMoreElements()) {
String key = keys.nextElement();System.out.println(key + " \t" + bundle.getHeaders().get(key));
}bundle.stop();
}
Seite 20
Events and Listener
Events
– Objects of type BundleEvent ➢ are generated by the framework➢ report on changes in the life-cycle of a bundle➢ are delivered to BundleListeners registered with the framework➢ have a type that represents the bundle's state change
INSTALLED, RESOVED, STARTED, ···
– Objects of type FrameworkEvent ➢ are generated by the framework➢ report on changes in the life-cycle of the framework➢ are delivered to FrameworkListeners registered with the framework➢ have a type that represents events within the framework
STARTED, ERROR, WARNING, ···
org.osgi.framework Class BundleEventorg.osgi.framework Class FrameworkEvent
Seite 21
Events and Listeners
Listener
– Objects of type BundleListner
➢ are registered with the framework (representet by a bundle context object)
➢ are called with an event of type BundleEvent when a bundle's life-cycle state has changed
– Objects of type FrameworkEvent ➢ are registered with the framework (representet by a bundle context
object)➢ are called with an event of type FrameworkEvent when the
framework starts, stops, is refreshed, or when an error occurs
org.osgi.framework Interface BundleListenerorg.osgi.framework Interface FrameworkListener
Seite 22
private static String decode(int type) { switch (type) { case 1: return "INSTALLED"; case 2: return "STARTED"; case 4: return "STOPPED"; case 8: return "UPDATED"; case 16: return "UNINSTALLED"; case 32: return "RESOLVED"; case 64: return "UNRESOLVED"; case 128: return "STARTING"; case 256: return "STOPPING"; case 512: return "LAZY_ACTIVATION"; default: return "??" + type + "??"; }}
Events and Listeners
Example : monitor bundle events
public void start(BundleContext bundleContext) throws Exception {
bundleContext.addBundleListener(new BundleListener() {@Overridepublic void bundleChanged(BundleEvent event) { System.out.println("EVENT : a Bundle event occured "); System.out.println("\t type: " + decode(event.getType())
+ "\n\t for bundle:" + event.getBundle().getSymbolicName());}});
Bundle bundle = bundleContext.installBundle("file:/home/thomas/tmp/RCP/plugins/HelloWorld_1.0.0.201106061603.jar");
bundle.start(); bundle.update(); bundle.stop(); bundle.uninstall();}
public void stop(BundleContext bundleContext) throws Exception { Activator.context = null; System.out.println("Goodby world - the bundle stops.");}
EVENT : a Bundle event occured Goodby world - the bundle stops. type: STARTED for bundle:HelloWorldEVENT : a Bundle event occured type: STOPPED for bundle:HelloWorldEVENT : a Bundle event occured type: UNRESOLVED for bundle:HelloWorldEVENT : a Bundle event occured type: UNINSTALLED for bundle:HelloWorldEVENT : a Bundle event occured type: STARTED for bundle:HelloWorldEVENT : a Bundle event occured type: STARTED for bundle:org.eclipse.osgi
org.osgi.framework.FrameworkEvent
Seite 23
Bundle Relations: Require / Import / Export
Seite 24
Bundle: Import / Export
Inter-bundle relationships– direct : Bundle A has access to bundle B via import / export
– indirect : Bundle A uses a service provided by bundle B, this relationship is always mediated by the framework
Direct usage Require Bundle
Import every package that is export by the bundle
Syntax:
Require-Bundle ::= bundle-description ( ',' bundle-description )*bundle-description ::= symbolic-name (';' parameter )*
Import Package Import named package of a bundle should be preferred in general Syntax:
Import-Package ::= import ( ',' import )*import ::= package-names ( ';' parameter )*package-names ::= package-name( ';' package-name )*
Seite 25
Bundle: Import – Export / Require Bundle
Import via Require Bundle
Example: Greeting Bundle
Exporter Create Plugin-Project “GreetingBundle” without Activator Create class greetingbundle.Hello with public method sayHello sayHello should print “Hello World” add
Export-Package: greetingbundle to the manifest
Importer Create Plugin-Project “GreetingUserBundle” with Activator add
Require-Bundle: GreetingBundle;bundle-version="1.0.0.0" to the manifest
Seite 26
Bundle: Import – Export / Require Bundle
package greetingbundle;
public class Hello { public void sayHello() { System.out.println("Hello! says the greeting bundle"); }}
Greeting Bundlecreate, add Class Hellochange version and provider
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: de.thm.mni.GreetingBundleBundle-SymbolicName: GreetingBundleBundle-Version: 1.0.0.0Bundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-Vendor: de.thm.mni
generated manifest
Seite 27
Bundle: Import – Export / Require Bundle
Greeting Bundleadd package export
modified manifest
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: de.thm.mni.GreetingBundleBundle-SymbolicName: GreetingBundleBundle-Version: 1.0.0.0Bundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-Vendor: de.thm.mniExport-Package: greetingbundle
Seite 28
Bundle: Import – Export / Require Bundle
Greeting User Bundle create using bundle, add require bundle
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: de.thm.mni.GreetingUserBundleBundle-SymbolicName: GreetingUserBundleBundle-Version: 1.0.0.0Bundle-Activator: greetinguserbundle.ActivatorImport-Package: org.osgi.framework;version="1.3.0"Bundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-Vendor: de.thm.mniRequire-Bundle: GreetingBundle;bundle-version="1.0.0"modified manifest
Seite 29
Bundle: Import – Export / Require Bundle
Greeting User Bundle create using/importing class ...
Eclipse manages import of required bundles!
Seite 30
Bundle: Import – Export / Require Bundle
Greeting User Bundle ... add using statement to activator
Seite 31
Bundle: Import - Export / Require Bundle
Export bundles (“plugins”)
create minimal configurationthen export as deployable plug-ins and fragments
Seite 32
Bundle: Import - Export / Require Bundle
Export bundles (“plugins”)
create minimal configuration (org.eclipse.osgi, GreetingUserBundle)then export as deployable plug-ins and fragments
Seite 33
Bundle: Import - Export / Require Bundle
Test bundles
osgi> ss
Framework is launched.
id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v20110210
osgi> install file:/home/thomas/tmp/RCP/plugins/GreetingBundle_1.0.0.0.jarBundle id is 4
osgi> install file:/home/thomas/tmp/RCP/plugins/GreetingUserBundle_1.0.0.0.jarBundle id is 5
osgi> ss
Framework is launched.
id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v201102104 INSTALLED GreetingBundle_1.0.0.05 INSTALLED GreetingUserBundle_1.0.0.0
osgi> start 4
osgi> start 5Hello! says the greeting bundle
osgi>
Seite 34
Bundle: Import - Export / Import Package
Import via Import Package
modify the using bundle GreetingUserBundle:
1. remove require bundle statement
Seite 35
Bundle: Import - Export / Import Package
Import via Import Package
modify the using bundle GreetingUserBundle:
2. Let Eclipse generate the import
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: de.thm.mni.GreetingUserBundleBundle-SymbolicName: GreetingUserBundleBundle-Version: 1.0.0.0Bundle-Activator: greetinguserbundle.ActivatorImport-Package: greetingbundle, org.osgi.framework;version="1.3.0"Bundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-Vendor: de.thm.mni
Seite 36
Bundle: Import - Export / Import Package
Import via Import Package
export the new version and test it
osgi> ss
Framework is launched.
id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v201102104 ACTIVE GreetingBundle_1.0.0.06 INSTALLED GreetingUserBundle_1.0.0.0
osgi> start 6Hello! says the greeting bundle
osgi> stop 6
osgi> uninstall 6
osgi> install file:/home/thomas/tmp/RCP/plugins/GreetingUserBundle_1.0.0.1.jarBundle id is 7
osgi> ss
Framework is launched.
id State Bundle0 ACTIVE org.eclipse.osgi_3.6.2.R36x_v201102104 ACTIVE GreetingBundle_1.0.0.07 INSTALLED GreetingUserBundle_1.0.0.1
osgi> start 7Hello! says the greeting bundle
Seite 37
Bundle: Import - Export / Version
Versions
– Bundle version Bundles have a version Default value : 0.0.0. Specified with the Bundle-Version header
Syntax:Bundle-Version ::= version
version ::= major( '.' minor ( '.' micro ( '.' qualifier )? )? )?
mayor ::= number
minor ::= number
micro ::= number
qualifier ::= ( alphanum | ’_’ | '-' )+
Components that are not specified, they have a default value of 0. If the qualifier component is not specified, it has a default value of the empty string.
Bundles are identified by the combination of symbolic name and version
Requiring bundle specifies a version constraintRequire-Bundle: <bundleName>; bundle-version=”<versionRange>”
Required bundle must match the version constraint
Seite 38
Bundle: Import - Export / Version
Versions
– Package version
Packages may have a version (not related to bundle version) Specified as part of the package import / export header Import specifies a version constraint
Import-Package: <packageName>; version=”<versionRange>”
Export must match the version constraint
Seite 39
Bundle: Import - Export / Version
Versions
– Version Ranges Example:
1.1 means all versions v with 1.1.0 <= v Example:
(1.1, 2.1] means all versions v with 1.1.0 < v <= 2.1.0
[ , ] range inclusive ( , ) range exclusive
Seite 40
Bundle: Import - Export / Dynamic Import
Dynamic Import of Packages
– Header:DynamicImport-Package:<comma separated list of package names with wildcards>
Example:DynamicImport-Package: *
– Packages are imported when neededDynamic Imports – The DynamicImport-Package header is intended to look for an exported package when that package is needed. The key use case for dynamic import is the Class forName method when a bundle does not know in advance the class name it may be requested to load. [OSGi-Spec]
Seite 41
Bundle: Class Loading
Class Loading– Each bundle has its own class loader
– Bundle loader is created by the framework after the bundle has been resolved
– Class loading in a bundle is performed in these steps:
java.* classesare loaded by the parent class loader of the bundle (usually the boot loader)
bundles referencing classes of imported packagesloading is delegated to the exporting bundle, starting with this step
bundles referencing classes of required other bundles or that are importing from several other bundlesdelegate loading to required bundles in the the order they appear in the manifest
the bundle class path is searched for the class
search for classes in exported packages ends here
if the class may be in a dynamically imported packagean appropriate exporter is searched, if successful, the class form now on is treated as if in an explicitly imported package
search for the class ends here
Seite 42
Bundle: Class Loading
OSGI-Spec.
Seite 43
Services
Seite 44
Services / Example
Introductory Example: Hello World Service
– Create plugin project HelloService
with activator
– Create plugin project HelloServiceUser
with activator
Seite 45
Services / Example
Hello World Service / define the service
package helloservice;
public interface HelloService { void sayHello();} the service definition as interface
package helloserviceImpl;
import helloservice.HelloService;
public class HelloServiceImpl implements HelloService {
@Override public void sayHello() { System.out.println("Hello - this service is brought to you by the HelloService"); }
}
the service implementation
Seite 46
Services / Example
Hello World Service / register the service in the activator
public class Activator implements BundleActivator {
private static BundleContext context;
. . .
public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; System.out.println("hello service started");
Class<?> serviceInterface = HelloService.class; Object serviceImpl = new HelloServiceImpl(); Dictionary<String, String> properties = new Hashtable<String, String>(); context.registerService(serviceInterface.getName(), serviceImpl, properties);
System.out.println("helloservice: HelloService registered"); } . . .}
Seite 47
Services / Example
Hello World Service / export package with service interface
Manifest-Version: 1.0Bundle-ManifestVersion: 2Bundle-Name: de.thm.mni.HelloServiceBundle-SymbolicName: HelloServiceBundle-Version: 1.0.0.0Bundle-Activator: helloservice.ActivatorImport-Package: org.osgi.framework;version="1.3.0"Bundle-RequiredExecutionEnvironment: JavaSE-1.6Bundle-Vendor: de.thm.mniExport-Package: helloservice
The generated manifest of the service bundle
Seite 48
Services / Example
Hello World Service User / use the service within the activator
The activator of the service user
Seite 49
Services / Example
Hello World Service User / use the service within the activator
The activator of the service user
package helloserviceuser;
import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;
import helloservice.HelloService;
public class Activator implements BundleActivator {
private static BundleContext context;
. . . public void start(BundleContext bundleContext) throws Exception { Activator.context = bundleContext; System.out.println("hello service user: started");
ServiceReference helloServiceRef = context.getServiceReference("helloservice.HelloService"); if (helloServiceRef == null) { System.out.println("hello service user: cannot reference hello service"); } else { try { System.out.println("hello service user: ServiceReference found " + helloServiceRef); HelloService helloService = (HelloService) context.getService(helloServiceRef); System.out.println("hello service user: hello service resolved " + helloService); helloService.sayHello(); } catch (Exception e) { System.out.println(e); } } } . . .}
Seite 50
Services / Example
Hello World Service / Test
When testing with eclipse make sure that the service defining bundle is started before the service user by setting appropriate start levels!
Seite 51
Services / Example
Hello World Service / Test
Seite 52
Services
Services
– ServiceAn object registered with the service registry under one or more interfaces together with properties. This object can be discovered and used by bundles.
– Service RegistryHolds the service registrations.
– Service ReferenceA reference to a service. Provides access to the service’s properties but not the actual service object. The service object must be acquired through a bundle’s Bundle Context.
RegistryRegistry
Service providerService provider
Service consumerService consumer
Service
Service Reference
Seite 53
Services
Service
Service nameFully qualified name of the service interface.
Service interfaceDefines the service “semantically”. - The class of the service object may also be used as “interface”.
Service objectImplementation of a service.Owned by and run within the defining bundle.
Service propertiesDictionary of key (a string) – value pairs which describe the service.(Optional)
Seite 54
Services
Service registration
Making a service available by publishing it.
Service may be ➢ unregistered explicitly➢ is unregistered implicitly when the registrating bundle is uninstalled
Registration in done by calling methods of a BundleContext➢ registerService(String name, Object service, Dictionary properties)
For a service object registered under a single service interface.➢ registerService(String[] names, Object service, Dictionary properies)
For a service object registered under multiple service interfaces.
Framework ensures that the registered object is an instance of the service interface and
returns a service reference object.
Seite 55
Services
Service locating
Get a reference to a service.
To use a service the user first has to obtain a service reference by calling methods of a BundleContext
➢ getServiceReference(String name)
Returns a reference to a service object registered under the name.➢ getServiceReference(String name, String filter)
Returns a reference to a service object registered under the name satisfying the filter.
To get a service object the user calls a method of a BundleContext➢ getService(ServiceReference reference)
Returns a service object.
Seite 56
Services / Properties
Service properties
java.util.Dictionary<String, ValueType> object, where ValueType should be a basic Java type defined in defined java.*
Properties describe the service and may be used to➢ get information about a service ➢ to query the registry for a service using a filter
in oder to find a matching service All keys
➢ are not case sensitive➢ are within common name-space when filtering and should be unique across
services Keys of the form “service.*” are reserved, some of them are predefined Filtering
➢ Filter: An expression according to the syntax of LDAP-search filters➢ may be used to match properties of a service reference
Seite 57
Services / Filter
Filtering Creation of filters is supported by objects of type BundleContext and by class FrameworkUtil:
Filter createFilter(String filter)throws InvalidSyntaxException
A filter supports matching:➢ match(ServiceReference)
Match the properties of the Service Reference performing key lookup in a case insensitive way.
➢ match(Dictionary)
Match the entries in the given Dictionary object performing key lookup in a case insensitive way.
➢ matchCase(Dictionary)
Match the entries in the given Dictionary object performing key lookup in a case sensitive way.
Example:
org.osgi.framework Interface Filter
String filterString = "(java.util.Currency=CHF)";Filter filter = FrameworkUtil.createFilter(filterString);if (filter.match(myServiceRef)) { MyService myService = (MyService) context.getService(myServiceRef);}
Seite 58
Services / Service Factory
Service Factories A Service Factory is a Service object that implements ServiceFactory
If the service objects implements this interface it will will not be returned directly by context.getService(ServiceReference)
instead context.getService delegates creation of the service object to its factory method:
getService(Bundle serviceUser, ServiceRegistration registObj)
This method is called by the Framework if a call is made to BundleContext.getService and the following are true:
➢ The ServiceReference argument to BundleContext.getService refers to a service object that implements the ServiceFactory interface.
➢ The bundle’s usage count of that service object is zero; that is, the bundle currently does not have any dependencies on the service object.
The call to BundleContext.getService must be routed by the framework to this method, passing to it the Bundle object of the caller.
org.osgi.framework Interface ServiceFactory
Seite 59
Services / Service Factory
package helloservice;
import org.osgi.framework.Bundle;import org.osgi.framework.ServiceFactory;import org.osgi.framework.ServiceRegistration;
public class HelloServiceFactory implements ServiceFactory {
@Override public Object getService(Bundle bundle, ServiceRegistration registration) { System.out.println("Hey bundle " + bundle + " needs my service"); return new HelloServiceImpl(); }
@Override public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {}}
package helloservice;
import java.util.Dictionary;import java.util.Hashtable;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception { Class<?> serviceInterface = HelloService.class; Object serviceImpl = new HelloServiceFactory(); Dictionary<String, String> properties = new Hashtable<String, String>(); context.registerService(serviceInterface.getName(), serviceImpl, properties); }
public void stop(BundleContext context) throws Exception {}}
Factory Example