Building OSGi Components Carsten Ziegeler | cziegeler@apache.org ApacheCon NA 2014 1
About cziegeler@apache.org @cziegeler RnD Team at Adobe Research Switzerland • Member of the Apache So fu ware Foundation • Apache Felix and Apache Sling (PMC and commi tu er) • And other Apache projects • OSGi Core Platform and Enterprise Expert Groups • Member of the OSGi Board • Book / article author, technical reviewer, conference speaker • 2
Agenda § 1 OSGi Service Registry § 2 Components § 3 Declarative Services Today § 4 Next version of Declarative Services 3
Component and Service § Component § Piece of so fu ware managed by a (component) container § Java: instances created and managed by a container § Container provides con fj guration and used services 4
Component and Service § Service § A component providing a service § Java: § De fj ned through an interface § A component implementing one or more interfaces (= services) § Usable by components and other services § Clients act on the service (interface) 5
Foreword § Many component frameworks for OSGi exist today § Di ffi culty of choosing § For OSGi based component development it’s more important to focus on the components than on the components framework § Focus is on developing components § Developers choice § Declarative Services is very good but it’s not the only solution 6
Example Application 7
OSGi Service Registry § Service oriented architecture § Publish/ fj nd/bind Service Registry Publish Find Service Description Service Service Provider Consumer Interact 8
Registering a Service § Each bundle has access to its bundle context object § Using bundle activator § Bundle context: § registerService(String, Object, Dictionary) § registerService(String[], Object, Dictionary) 9
Registering a Service § Each bundle has access to its bundle context object § Using bundle activator § Bundle context: § registerService(String, Object, Dictionary) § registerService(String[], Object, Dictionary) Service name(s) 10
Registering a Service § Each bundle has access to its bundle context object § Using bundle activator § Bundle context: § registerService(String, Object, Dictionary) § registerService(String[], Object, Dictionary) Service name(s) Service instance 11
Registering a Service § Each bundle has access to its bundle context object § Using bundle activator § Bundle context: § registerService(String, Object, Dictionary) § registerService(String[], Object, Dictionary) Service name(s) Service instance Service properties 12
Registering a Service § Each bundle has access to its bundle context object § Using bundle activator § Bundle context: § registerService(String, Object, Dictionary) § registerService(String[], Object, Dictionary) import import org.osgi.framework.Constants org.osgi.framework.Constants; import import org.osgi.framework.ServiceRegistration org.osgi.framework.ServiceRegistration; … BundleContext bc = …; final final Dictionary<String, Object> props = Dictionary<String, Object> props = new new Hashtable Hashtable<String, Object>(); <String, Object>(); props.put(Constants. SERVICE_DESCRIPTION, "Greatest Service on Earth"); props.put(Constants. SERVICE_VENDOR, "Adobe Systems Incorporated"); final final Scheduler service = Scheduler service = new new MyScheduler MyScheduler(); (); this.bundleContext this bundleContext.registerService .registerService( new new String[] { String[] {Scheduler.class.getName Scheduler.class.getName()}, ()}, service, props); service, props); 13
Ge tu ing a Service from the Service Registry BundleContext bundleContext = ... ...; final ServiceReference final ServiceReference sr sr = = bundleContext.getServiceReference bundleContext.getServiceReference( Scheduler.class.getName Scheduler.class.getName()); ()); if ( if ( sr sr != != null null ) { ) { final final Scheduler s = (Scheduler) Scheduler s = (Scheduler) bundleContext.getService bundleContext.getService(sr sr); ); if if ( s != ( s != null null ) { ) { s.doSomething(); } bundleContext.ungetService(sr); } 14
Ge tu ing Service Properties BundleContext bundleContext = ... ...; final final ServiceReference ServiceReference sr sr = = bundleContext.getServiceReference bundleContext.getServiceReference( Scheduler.class.getName Scheduler.class.getName()); ()); if if ( ( sr sr != != null null ) { ) { // access properties // access properties final final Object value = Object value = sr.getProperty(Constants. SERVICE_VENDOR); bundleContext.ungetService(sr); } 15
Service Properties import import org.osgi.framework.Constants org.osgi.framework.Constants; Constants. SERVICE_ID - set by the framework (long) id of the service increased for each registration dynamic - not persisted! Constants. SERVICE_DESCRIPTION - optional description (string) Constants. SERVICE_VENDOR - optional vendor (string) Constants. SERVICE_PID - persistence identifier (string) optional, unique identifier Constants. SERVICE_RANKING - ordering of registrations 16
Multiple Registrations for a Service BundleContext bundleContext = ... ...; final final ServiceReference ServiceReference[] refs = [] refs = bundleContext.getServiceReferences bundleContext.getServiceReferences( Scheduler.class.getName Scheduler.class.getName(), (), null); null); if if ( refs != ( refs != null null ) { ) { // iterate over references, maybe sort by ranking etc. // iterate over references, maybe sort by ranking etc. } 17
Ge tu ing a Service from the Service Registry BundleContext bundleContext = ... ...; final ServiceReference final ServiceReference sr sr = = bundleContext.getServiceReference bundleContext.getServiceReference( Scheduler.class.getName Scheduler.class.getName()); ()); if ( if ( sr sr != != null null ) { ) { final final Scheduler s = (Scheduler) Scheduler s = (Scheduler) bundleContext.getService bundleContext.getService(sr sr); ); if if ( s != ( s != null null ) { ) { s.doSomething(); } bundleContext.ungetService(sr); } Highest Ranking 18
Lazy Service Creation / Bundle Scope • Register service factory instead of service • Framework calls factory once per client bundle public public interface interface org.osgi.framework.ServiceFactory org.osgi.framework.ServiceFactory { { Object Object getService getService(Bundle bundle, (Bundle bundle, ServiceRegistration ServiceRegistration registration); registration); void void ungetService ungetService(Bundle bundle, (Bundle bundle, ServiceRegistration ServiceRegistration registration, registration, service); service); } 19
Registering a Service Factory import import org.osgi.framework.Constants org.osgi.framework.Constants; import org.osgi.framework.ServiceRegistration import org.osgi.framework.ServiceRegistration; … BundleContext bc = …; final final Dictionary<String, Object> props = Dictionary<String, Object> props = new new Hashtable Hashtable<String, Object>(); <String, Object>(); props.put(Constants. SERVICE_DESCRIPTION, "Greatest service on Earth"); props.put(Constants. SERVICE_VENDOR, "Adobe Systems Incorporated"); final final ServiceFactory ServiceFactory factory = factory = new new MySchedulerFactory MySchedulerFactory(); (); this this.bundleContext bundleContext.registerService .registerService( new new String[] { String[] {Scheduler.class.getName Scheduler.class.getName()}, ()}, factory, props); factory, props); 20
Service Event Listener • Noti fj cation of registration / unregistrations • Registered to the bundle context • Filter for service name, properties etc. package package org.osgi.framework org.osgi.framework; public interface public interface ServiceListener ServiceListener extends extends EventListener EventListener { { void void serviceChanged serviceChanged(ServiceEvent ServiceEvent event); event); } 21
OSGi Service Registry • Lightweight services • Lookup is based on interface name • Direct method invocation • Scopes: singleton, bundle, prototype (R6) • Good design practice • Separates interface from implementation • Separates registration from usage • Enables reuse, substitutability, loose coupling, and late binding 22
Example Application 23
OSGi Service Registry § Powerful but "complicated" to use directly § Requires a di ff erent way of thinking § Dynamic § Packages/Bundles might come and go § Services might appear/disappear § Manually resolve and track services § Doable, but requires "work" 24
Components and Services with OSGi § Service interface § Public (if exported for other bundles) § Versioned through package version (Semantic versioning) § Private for internal services (sometimes useful) § Component / service implementation § Always private 25
Component Container Interaction OSGi Service Registry "Manual Access" Declarative Blueprint iPojo Services 26
Recommend
More recommend