SlideShare a Scribd company logo
OSGi Bootcamp
Day 1
Jan Willem Janssen
Agenda
• Introduction to OSGi
• The core framework
• creating bundles, working with services, dealing
with the dynamics and version resolution
OSGi history
• Started as an embedded platform for the “home gateway”
• Originally under the JCP as JSR-8 (1999)
• OSGi alliance, consists of a large number of big companies, with
the following mission:
• Maintaining and publicising the OSGi specification
• Certifying implementations
• Organising events
• Current version: OSGi Release 6
OSGi releases
• R1: long ago :)
• R2: October 2001 - JES, Oscar
• R3: March 2003 - Knopflerfish
• R4: August 2005 - Equinox
• 4.1: May 2007 - small updates
• 4.2: September 2009 - moving to the Enterprise
• 4.3: April 2011 - generics & framework hooks
• R5: June 2012 - generic resource/capability model
• R6: June 2014 - framework updates
• R7: 2016? - IoT ?
OSGi today
OSGi technology is the dynamic module system for Java™

OSGi technology is Universal Middleware.

OSGi technology provides a service-oriented, component-
based environment for developers and offers standardized
ways to manage the software lifecycle. These capabilities
greatly increase the value of a wide range of computers and
devices that use the Java™ platform.
OSGi Alliance
• Expert Groups:
• core platform (CPEG)
• enterprise (EEG)
• residential (REG)
• IoT (IEG)
• Working Groups:
• marketing
• requirements
• technical steering committee
OSGi specification
• Core
• semantics
• framework
• core/mandatory services
• Companion
• optional services
Service
Life%cycle
Module
OSGi Framework
Java$Virtual$Machine
Security
Bundle Bundle Bundle
OSGi%framework
OSGi Framework Layering
Provides a publish/find/bind service
model to for bundles to
communicate in a decoupled way
service
module
life-cycle
Creates the concept of bundles that
share classes in a controlled way
according to constraints
Manages the life cycle of bundles in
a framework without requiring the
VM be restarted
Module Layer (1/3)
• A bundle is:
• a JAR file
• unit of deployment
• own class loader
• isolation
• bundle classpath
store
Store.class
Key.class
store.fs
StoreImpl.class
FileSystem.class
StreamU4l.class
bundle
store.fs.osgi
Ac4vator.class
META%INF/MANIFEST.MF
Bundle%SymbolicName::store.fs
Bundle%Version::1.0.2
Bundle%Classpath::.,:lib/fsuGl.jar
Bundle%AcGvator:
:store.fs.osgi.AcGvator
Module Layer (2/3)
fs.nio3
Input.class
Output.class
store
Store.class
Key.class
store.fs
StoreImpl.class
FileSystem.class
StreamU4l.class
bundle
store.fs.osgi
Ac4vator.class
META%INF/MANIFEST.MF
Bundle%SymbolicName::store.fs
Bundle%Version::1.0.2
Bundle%Classpath::.,:lib/fsuGl.jar
Bundle%AcGvator:
:store.fs.osgi.AcGvator
Export%Package::store:2.5.0
Import%package::fs.nio3:[1,:3)
Module Layer (3/3)
ModuleBundle Bundle Bundle Bundle
exports
imports
exports
imports
exports
exports
org.apache.u5l61.0
org.apache.u5l61.1org.apache.log62.3
org.apache.db61.4
• Consistency
- ensures constraints are not
violated
• Class visibility
- exporters may include/exclude
specific classes
• Bundle fragments
- a single logical module in
multiple physical bundles
• Bundle dependencies
- Allows for tight coupling when
required
• Imagine bundle A somehow gets servlet instances
from bundle B
Importing & Exporting a
Package (1/4)
A
B
import
javax.servlet
export
javax.servlet
.class
one3copy3of
javax.servlet
• What if bundle A also wanted to get servlet instances
somehow from bundle C?
Importing & Exporting a
Package (1/4)
A
B
import
javax.servlet
export
javax.servlet
.class
one3copy3of
javax.servlet
• Bundle C could import from bundle B, but then it is
dependent on it
Importing & Exporting a
Package (2/4)
A
B
import
javax.servlet
export
javax.servlet
.class
one3copy3of
javax.servlet
C
import
javax.servlet
• Bundle C could export its own servlet package, but
bundle A could only see either C or B
Importing & Exporting a
Package (3/4)
A
C
import
javax.servlet
export
javax.servlet
.class
two3copies3of
javax.servlet
B
export
javax.servlet
.class
???
Importing & Exporting a
Package (4/4)
• Bundle C could both import and export servlet to solve
the dilemma
A
C
import
javax.servlet
export1and1import
javax.servlet
.class
B
.class
export1and1import
javax.servlet
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
Interface
package org.foo.http;
import javax.servlet;
public interface HttpService {
void registerServlet(Sting alias, Servlet servlet);
}
Metadata
Export-Package: org.foo.http; version="1.0.0"
Import-Package: javax.servlet; version="2.3.0"
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
import
javax.servlet
version=2.3.0
export
javax.servlet
version=2.3.0
export
org.foo.h=p
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
import
javax.servlet
version=2.3.0
export
javax.servlet
version=2.3.0
export
org.foo.h=p
HTTP$
client
import
org.foo.h=p
import
javax.servlet
version=2.4.0
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
export
javax.servlet
version=2.3.0
export
org.foo.h<p
HTTP$
client
B
export
javax.servlet
version=2.4.0
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
export
javax.servlet
version=2.3.0
export
org.foo.h<p
HTTP$
client
B
export
javax.servlet
version=2.4.0
This would result in a
ClassCastException,
why?
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
export
javax.servlet
version=2.3.0
export
org.foo.h<p
HTTP$
client
B
export
javax.servlet
version=2.4.0
Advanced Consistency
Checking
• Sometimes more advanced consistency checking is
necessary, consider this:
HTTP$
service
A
export
javax.servlet
version=2.3.0
export
org.foo.h<p
HTTP$
client
B
export
javax.servlet
version=2.4.0
"uses"
We need to declare such
internal dependencies!
Metadata
Export-Package: org.foo.http; version=“1.0.0"; uses:="javax.servlet"
Import-Package: javax.servlet; version="2.3.0"
Example Manifest
Bundle-ManifestVersion: 2 

Bundle-Name: Example Bundle

Bundle-SymbolicName: net.luminis.example.bundle

Bundle-Version: 1.0.0

Import-Package: 

org.osgi.framework;version=“1.3“, 

org.osgi.service.event;version=“[1.1,2.0)“, 

net.luminis.foo;resolution:=“optional“

Export-Package: 

org.osgi.service.event;uses:=org.osgi.framework;version=“1.1”



X-MyBundleHeader:

custom-attribute=“my-value”
Lifecycle Layer
• Managed life cycle:
- states for each bundle
• Allows updating existing
bundles
- dynamically install, start,
update, and uninstall
Life%cycle
start
end
install
start
stopuninstall
installed
star2ng
stopping
ac2veresolved
uninstalled
Lifecycle Example
Bundle
OSGi+Framework
provided
package
Bundle
OSGi+Framework
Bundle
Lifecycle Example
install
bundle
Lifecycle Example
Bundle
OSGi+Framework
Bundle
resolve
bundle
Lifecycle Layer
• The framework instantiates a class implementing
BundleActivator
• declared in the manifest
• bootstraps your code by invoking start()
• provides you a BundleContext for framework
interaction
Lifecycle Layer
public interface BundleContext {

// …

public Bundle[] getBundles();

public Bundle installBundle(String location, InputStream input) 

throws BundleException;
public void addServiceListener(ServiceListener listener);

public void addBundleListener(BundleListener listener);

public void addFrameworkListener(FrameworkListener listener);
public ServiceRegistration registerService(String clazz, 

Object service, Dictionary properties);
public ServiceReference[] getServiceReferences(String clazz, 

String filter) throws InvalidSyntaxException;
public Object getService(ServiceReference reference);

// …

}
Service Layer
• OSGi framework 

promotes service 

oriented interaction 

pattern among 

bundles
Service
Log Store
publish use
use
publish
Prefs
publish
use
Bundle Bundle Bundle Bundle
Service'
Provider
Service'
Requester
Service'
Registry
publish
interact
find
Service Example
Bundle
OSGi+Framework
provided
package
provided
service
Service Example
Bundle
OSGi+Framework
Bundle
install
bundle
Service Example
Bundle
OSGi+Framework
Bundle
resolve
bundle
Service Example
Bundle
OSGi+Framework
Bundle
resolve
service
Registering a service
public class Activator implements BundleActivator {

public void start(BundleContext context) throws Exception {

Properties props = new Properties();

props.put("author", "Jan Willem");



context.registerService(

MyService.class.getName(), new MyServiceImpl(), props);

}
public void stop(BundleContext context) throws Exception {

// framework unregisters our services on our behalf…

}

}
Looking up and using a service
1. lookup a ServiceReference
2. get a reference to the service
3. invoke the method
4. (optional: unget the service)
Looking up and using a service
ServiceReference reference = 

context.getServiceReference(MyFirstService.class.getName());

if (reference != null) {

MyFirstService srv = 

(MyFirstService) context.getService(reference);

if (srv != null) {

// use service

// …

context.ungetService(reference);

} else {

System.out.println("No service found");

}

} else {

System.out.println("No service reference found!");

}
Looking up using a query
• You can both query on the service name and a filter
condition
• The filter condition allows you to query for properties
• The filter syntax is similar to LDAP:
• (key=value) or (&(name=john)(age>=18))
context.getServiceReferences(

MyFirstService.class.getName(), 

"(author=Jan Willem)");
Listening to the service registry
• Using the bundle context, register as a ServiceListener
• serviceChanged() will be invoked when a service is:
• registered;
• modified;
• unregistering.
public interface ServiceListener extends EventListener {

public void serviceChanged(ServiceEvent event);

}
Introducing the ServiceTracker
• Makes the task of tracking services easier
• You can just ask the ServiceTracker for a (list of)
service(s) that match the conditions you specified
• A ServiceTrackerCustomizer can be used to
monitor changes or customise the service reference
that is returned by the tracker
• Found in org.osgi.util.tracker package
ServiceTracker example
private ServiceTracker m_tracker;
// initialise:

m_tracker = new ServiceTracker(context, MyService.class.getName(), null);

m_tracker.open();


// usage:

SomeService service = (SomeService) m_tracker.getService();

if (service != null) {

service.greet("John");

}

// cleanup:

m_tracker.close();
Version Format
• OSGi uses a 4-part version numbering scheme
• <major>.<minor>.<micro>.<qualifier>
• Major, minor, and micro are numeric values
• Qualifier is a string value
• Comparison (not always intuitive)
• 1.0.0 < 1.9.9 < 1.10
• 1.0.0.beta > 1.0.0.alpha > 1.0.0
Version Format
• Valid:
• 1
• 1.10
• 1.9.9.alpha
• 0.2.0.SNAPSHOT
• Invalid:
• 0.2.SNAPSHOT
• 1.9.9-alpha
Version Range Format
• Interval notation is used for version ranges
• use '[' or ']' for inclusive values
• use '(' or ')' for exclusive values
Version Range Format
• Examples (quotes needed)
• "[1.0.0,2.0.0)" == (1.0.0 <= v < 2.0.0)
• "[1.1.2,1.2.3]" == (1.2.3 <= v <= 1.2.3)
• "[1.1,2)" == (1.1.0 <= v < 2.0.0)
• When a version range is expected, a single value
represents an infinite range:
• "1.0.0" == (1.0.0 <= v < ∞)
Semantic versioning
• Major number change – signifies a backward
incompatible update.
• Minor number change – signifies a backward
compatible update.
• Micro number change – signifies an internal update
(e.g., a bug fix or performance improvement).
• Qualifier change – signifies a trivial internal change with
“outward” noticeable difference, but nonetheless is a
new artifact (e.g., line number refactoring).
Semantic versioning
• OSGi whitepaper on semantic versioning
• semver.org semantic versioning manifest
Downsides and Pitfalls
<<"client">> Foo
getBar()
FooImpl
<<"client">> Foo
getBar()
setBar()
FooImpl
uses
implements
update
implements
uses
Best Practice
<<"client">> Foo
FooImpl
uses
implements
[1.0,/2.0)
[1.0,/1.1)

More Related Content

OSGi bootcamp - part 1

  • 1. OSGi Bootcamp Day 1 Jan Willem Janssen
  • 2. Agenda • Introduction to OSGi • The core framework • creating bundles, working with services, dealing with the dynamics and version resolution
  • 3. OSGi history • Started as an embedded platform for the “home gateway” • Originally under the JCP as JSR-8 (1999) • OSGi alliance, consists of a large number of big companies, with the following mission: • Maintaining and publicising the OSGi specification • Certifying implementations • Organising events • Current version: OSGi Release 6
  • 4. OSGi releases • R1: long ago :) • R2: October 2001 - JES, Oscar • R3: March 2003 - Knopflerfish • R4: August 2005 - Equinox • 4.1: May 2007 - small updates • 4.2: September 2009 - moving to the Enterprise • 4.3: April 2011 - generics & framework hooks • R5: June 2012 - generic resource/capability model • R6: June 2014 - framework updates • R7: 2016? - IoT ?
  • 5. OSGi today OSGi technology is the dynamic module system for Java™ OSGi technology is Universal Middleware. OSGi technology provides a service-oriented, component- based environment for developers and offers standardized ways to manage the software lifecycle. These capabilities greatly increase the value of a wide range of computers and devices that use the Java™ platform.
  • 6. OSGi Alliance • Expert Groups: • core platform (CPEG) • enterprise (EEG) • residential (REG) • IoT (IEG) • Working Groups: • marketing • requirements • technical steering committee
  • 7. OSGi specification • Core • semantics • framework • core/mandatory services • Companion • optional services
  • 9. OSGi Framework Layering Provides a publish/find/bind service model to for bundles to communicate in a decoupled way service module life-cycle Creates the concept of bundles that share classes in a controlled way according to constraints Manages the life cycle of bundles in a framework without requiring the VM be restarted
  • 10. Module Layer (1/3) • A bundle is: • a JAR file • unit of deployment • own class loader • isolation • bundle classpath store Store.class Key.class store.fs StoreImpl.class FileSystem.class StreamU4l.class bundle store.fs.osgi Ac4vator.class META%INF/MANIFEST.MF Bundle%SymbolicName::store.fs Bundle%Version::1.0.2 Bundle%Classpath::.,:lib/fsuGl.jar Bundle%AcGvator: :store.fs.osgi.AcGvator
  • 12. Module Layer (3/3) ModuleBundle Bundle Bundle Bundle exports imports exports imports exports exports org.apache.u5l61.0 org.apache.u5l61.1org.apache.log62.3 org.apache.db61.4 • Consistency - ensures constraints are not violated • Class visibility - exporters may include/exclude specific classes • Bundle fragments - a single logical module in multiple physical bundles • Bundle dependencies - Allows for tight coupling when required
  • 13. • Imagine bundle A somehow gets servlet instances from bundle B Importing & Exporting a Package (1/4) A B import javax.servlet export javax.servlet .class one3copy3of javax.servlet
  • 14. • What if bundle A also wanted to get servlet instances somehow from bundle C? Importing & Exporting a Package (1/4) A B import javax.servlet export javax.servlet .class one3copy3of javax.servlet
  • 15. • Bundle C could import from bundle B, but then it is dependent on it Importing & Exporting a Package (2/4) A B import javax.servlet export javax.servlet .class one3copy3of javax.servlet C import javax.servlet
  • 16. • Bundle C could export its own servlet package, but bundle A could only see either C or B Importing & Exporting a Package (3/4) A C import javax.servlet export javax.servlet .class two3copies3of javax.servlet B export javax.servlet .class ???
  • 17. Importing & Exporting a Package (4/4) • Bundle C could both import and export servlet to solve the dilemma A C import javax.servlet export1and1import javax.servlet .class B .class export1and1import javax.servlet
  • 18. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: Interface package org.foo.http; import javax.servlet; public interface HttpService { void registerServlet(Sting alias, Servlet servlet); } Metadata Export-Package: org.foo.http; version="1.0.0" Import-Package: javax.servlet; version="2.3.0"
  • 19. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A import javax.servlet version=2.3.0 export javax.servlet version=2.3.0 export org.foo.h=p
  • 20. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A import javax.servlet version=2.3.0 export javax.servlet version=2.3.0 export org.foo.h=p HTTP$ client import org.foo.h=p import javax.servlet version=2.4.0
  • 21. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A export javax.servlet version=2.3.0 export org.foo.h<p HTTP$ client B export javax.servlet version=2.4.0
  • 22. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A export javax.servlet version=2.3.0 export org.foo.h<p HTTP$ client B export javax.servlet version=2.4.0 This would result in a ClassCastException, why?
  • 23. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A export javax.servlet version=2.3.0 export org.foo.h<p HTTP$ client B export javax.servlet version=2.4.0
  • 24. Advanced Consistency Checking • Sometimes more advanced consistency checking is necessary, consider this: HTTP$ service A export javax.servlet version=2.3.0 export org.foo.h<p HTTP$ client B export javax.servlet version=2.4.0 "uses" We need to declare such internal dependencies! Metadata Export-Package: org.foo.http; version=“1.0.0"; uses:="javax.servlet" Import-Package: javax.servlet; version="2.3.0"
  • 25. Example Manifest Bundle-ManifestVersion: 2 
 Bundle-Name: Example Bundle
 Bundle-SymbolicName: net.luminis.example.bundle
 Bundle-Version: 1.0.0
 Import-Package: 
 org.osgi.framework;version=“1.3“, 
 org.osgi.service.event;version=“[1.1,2.0)“, 
 net.luminis.foo;resolution:=“optional“
 Export-Package: 
 org.osgi.service.event;uses:=org.osgi.framework;version=“1.1”
 
 X-MyBundleHeader:
 custom-attribute=“my-value”
  • 26. Lifecycle Layer • Managed life cycle: - states for each bundle • Allows updating existing bundles - dynamically install, start, update, and uninstall Life%cycle start end install start stopuninstall installed star2ng stopping ac2veresolved uninstalled
  • 30. Lifecycle Layer • The framework instantiates a class implementing BundleActivator • declared in the manifest • bootstraps your code by invoking start() • provides you a BundleContext for framework interaction
  • 31. Lifecycle Layer public interface BundleContext {
 // …
 public Bundle[] getBundles();
 public Bundle installBundle(String location, InputStream input) 
 throws BundleException; public void addServiceListener(ServiceListener listener);
 public void addBundleListener(BundleListener listener);
 public void addFrameworkListener(FrameworkListener listener); public ServiceRegistration registerService(String clazz, 
 Object service, Dictionary properties); public ServiceReference[] getServiceReferences(String clazz, 
 String filter) throws InvalidSyntaxException; public Object getService(ServiceReference reference);
 // …
 }
  • 32. Service Layer • OSGi framework 
 promotes service 
 oriented interaction 
 pattern among 
 bundles Service Log Store publish use use publish Prefs publish use Bundle Bundle Bundle Bundle Service' Provider Service' Requester Service' Registry publish interact find
  • 37. Registering a service public class Activator implements BundleActivator {
 public void start(BundleContext context) throws Exception {
 Properties props = new Properties();
 props.put("author", "Jan Willem");
 
 context.registerService(
 MyService.class.getName(), new MyServiceImpl(), props);
 } public void stop(BundleContext context) throws Exception {
 // framework unregisters our services on our behalf…
 }
 }
  • 38. Looking up and using a service 1. lookup a ServiceReference 2. get a reference to the service 3. invoke the method 4. (optional: unget the service)
  • 39. Looking up and using a service ServiceReference reference = 
 context.getServiceReference(MyFirstService.class.getName());
 if (reference != null) {
 MyFirstService srv = 
 (MyFirstService) context.getService(reference);
 if (srv != null) {
 // use service
 // …
 context.ungetService(reference);
 } else {
 System.out.println("No service found");
 }
 } else {
 System.out.println("No service reference found!");
 }
  • 40. Looking up using a query • You can both query on the service name and a filter condition • The filter condition allows you to query for properties • The filter syntax is similar to LDAP: • (key=value) or (&(name=john)(age>=18)) context.getServiceReferences(
 MyFirstService.class.getName(), 
 "(author=Jan Willem)");
  • 41. Listening to the service registry • Using the bundle context, register as a ServiceListener • serviceChanged() will be invoked when a service is: • registered; • modified; • unregistering. public interface ServiceListener extends EventListener {
 public void serviceChanged(ServiceEvent event);
 }
  • 42. Introducing the ServiceTracker • Makes the task of tracking services easier • You can just ask the ServiceTracker for a (list of) service(s) that match the conditions you specified • A ServiceTrackerCustomizer can be used to monitor changes or customise the service reference that is returned by the tracker • Found in org.osgi.util.tracker package
  • 43. ServiceTracker example private ServiceTracker m_tracker; // initialise:
 m_tracker = new ServiceTracker(context, MyService.class.getName(), null);
 m_tracker.open(); 
 // usage:
 SomeService service = (SomeService) m_tracker.getService();
 if (service != null) {
 service.greet("John");
 }
 // cleanup:
 m_tracker.close();
  • 44. Version Format • OSGi uses a 4-part version numbering scheme • <major>.<minor>.<micro>.<qualifier> • Major, minor, and micro are numeric values • Qualifier is a string value • Comparison (not always intuitive) • 1.0.0 < 1.9.9 < 1.10 • 1.0.0.beta > 1.0.0.alpha > 1.0.0
  • 45. Version Format • Valid: • 1 • 1.10 • 1.9.9.alpha • 0.2.0.SNAPSHOT • Invalid: • 0.2.SNAPSHOT • 1.9.9-alpha
  • 46. Version Range Format • Interval notation is used for version ranges • use '[' or ']' for inclusive values • use '(' or ')' for exclusive values
  • 47. Version Range Format • Examples (quotes needed) • "[1.0.0,2.0.0)" == (1.0.0 <= v < 2.0.0) • "[1.1.2,1.2.3]" == (1.2.3 <= v <= 1.2.3) • "[1.1,2)" == (1.1.0 <= v < 2.0.0) • When a version range is expected, a single value represents an infinite range: • "1.0.0" == (1.0.0 <= v < ∞)
  • 48. Semantic versioning • Major number change – signifies a backward incompatible update. • Minor number change – signifies a backward compatible update. • Micro number change – signifies an internal update (e.g., a bug fix or performance improvement). • Qualifier change – signifies a trivial internal change with “outward” noticeable difference, but nonetheless is a new artifact (e.g., line number refactoring).
  • 49. Semantic versioning • OSGi whitepaper on semantic versioning • semver.org semantic versioning manifest
  • 50. Downsides and Pitfalls <<"client">> Foo getBar() FooImpl <<"client">> Foo getBar() setBar() FooImpl uses implements update implements uses