OSGi Training
Aruna Karunarathna
Senior Software Engineer
Modularity in Java
Why Modularity
o Ease of development (interactions are clearly defined)
o Pluggable modules
o Reusable modules
Is Java providing the modularity?
o Compile time vs Runtime difference
o Compiled and run under single/flat classpath
o Alternatives
o Write custom classloaders / non standard way to handle
Java Classloading...
http://www.techjava.de/topics/2008/01/java-class-loading/
Java Compile Time vs Runtime...
axiom-1.2.0.jar axis2-1.4.5.jar log4j.1.4.1..jar saxon.14.1..jar algpr.1.3.2..jar spring.0.2.1..jar
spring-core.0.34.1..jar abdera_1.0.0..jar ajaxtags_1.3.0.beta-rc7-.jar annogen_0.1.0..jar antlr_3.2.0..jar apache-zookeeper_3.3.4..jar
JAR (Java Archive)
o Development units in java
o Application contains several jar files
o At runtime there is no real meaning for a jar file
o All the developed Jar files treated as a single, ordered,
global list which is called the classpath.
JAR (Java Archive) cntd..
o Problems with JAR Files
- Multiple versions of JAR files cannot be loaded at same time
- A JAR cannot declare dependencies on other JARs.
- No mechanism for information hiding
- Jars cannot be treated as modules.
o Hence Java is suffering from modularity.. :(
Dynamism in Java
o Can a Jar file updated while the application is running?
o Can new functionality be added while the application is
running? (Update a class file with new version)
o The application (JVM), needs to be restarted.
o Java lacks Dynamism.
OSGi for the rescue?
o Widely accepted way (A specification) of developing modular
and dynamic systems using Java [1].
o OSGi Framework implementations (Open Source)
o Equinox
o Knopflerfish
o Apache
[1]. https://www.osgi.org/developer/specifications/
Bundles
o Bundles are the development unit of OSGi
o Typical OSGi application consists with multiple bundles
o Bundles can share packages and hide packages in a consistent
manner
Most Importantly
o What changes there in bundles, when comparing to JAR files?
MANIFEST.MF
o Use some standard MANIFEST Headers.
o Defines the bundle’s identity
o Specifies the packages on which
this bundle depends
o Specifies the packages on which this
bundle exports
o Declares additional human-readable
information
Manifest-Version: 1.0
Bnd-LastModified: 1405099135557
Build-Jdk: 1.7.0_55
Built-By: aruna
Bundle-Activator: org.sample.Activator
Bundle-ManifestVersion: 2
Bundle-Name: sample
Bundle-SymbolicName: sample
Bundle-Vendor: WSO2 Inc
Bundle-Version: 1.0.0
Created-By: Apache Maven Bundle Plugin
Export-Package:
org.sample;uses:="org.osgi.framework";
version="1.0.0"
Import-Package:
org.osgi.framework;version="[1.7,2)"
Tool: Bnd-2.1.0.20130426-122213
Bundles cntd..
o Standard Java - Place Jar files in classpath
o OSGi Framework - Install bundles to framework
Java class loading with OSGi...
Lifecycle State Diagram
DEMO
o OSGi Framework
o First Look at a Sample Bundle
o Try out the lifecycle events
of a bundle
http://www.slideshare.net/rossmason/realtime-apis
Bundle Activator Manifest Entry
o Bundle Activator Manifest Entry is the hook to the Bundle execution entry
point.
o Similar to the Main Method of a Jar file?..
o Header value specifies the name of a reachable class
o Either a class in an Imported Package
o A class in the Bundle class path
o This class implements the org.osgi.framework.BundleActivator interface, and
implements the following two methods.
o Can use these two methods to customize the behaviours when the bundle is
started and stopped.
public interface BundleActivator {
void start(org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception;
void stop(org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception;
}
Bundle Activator Manifest Entry cntd...
o When the bundle installed and started, OSGi Framework creates an instance of
Bundle Activator class and call the start() method.
o When the bundle stop is initiated, OSGi Framework call the stop() method.
o In practice when the stop is called, you should undo everything you did in
the start method.
o The activator instance on which start() is called is the same instance
on which stop() is called.
o The activator instance is discarded and isn’t used again, after stop()
is called.
o If the bundle is subsequently restarted after being stopped, a new
activator instance is created, and the start() and stop() methods are
invoked on it as appropriate.
Bundle Context
o Can be accessed via start() and stop() of Bundle Activator class
o Bundle context object is its role as the unique execution context of its
associated bundle
o Valid while the bundle is active. (The time range from the framework call
start() up until to the stop() is called )
o Gain access to two types of methods
o Related to deployment and lifecycle management.
o Related to bundle interaction via services.
o They should be treated as sensitive or private objects and not passed freely
among bundles
Listening for events
o OSGi framework supports two types of events: BundleEvents and FrameworkEvents
o The former event type reports changes in the lifecycle of bundles, whereas the
latter reports framework-related changes
o The BundleContext object has methods to register BundleListener and
FrameworkListener objects for receiving BundleEvent and FrameworkEvent
notifications, respectively
o How to implement BundleListener and FrameworkListener in your code?.
a. Create a new class which Implements BundleListener or FrameworkListener
b. Implement the bundleChanged(BundleEvent) or frameworkEvent(FrameworkEvent)
methods respectively.
c. Register by creating a new Object of the implemented class to the
BundleContext as a Listener using the bundleContext.addBundleListener() or
bundleContext.addFrameworkListener() respectively.
o No need to call the removeBundleListener() or removeFrameworkListener(), which will
automatically removed when the bundle is stopped.
Relationship between carbon & OSGi
Non OSGi Portion OSGi Portion
./carbon.sh
org.wso2.carbon.l
auncher-5.2.0.jar
Equinox + Some
Carbon Bundles
Bundles developed
by Component
Developers
What about Dynamism?
o After the Objects are instantiated, they will tightly coupled
with the modules.
o What if we want to change the module or part of the module,
dynamically at the runtime?
OSGi Services Layer
o Kind of in VM SOA model
o OSGi Registry
o OSGi Service is simply a Java Object
published to the service registry
o Services are published/looked up
Using an exported interface.
OSGi Service
Registry
Service Provider Service Consumer
Publish Find
Registering an OSGi Service
public class Activator implements BundleActivator {
ServiceRegistration serviceRegistration;
public void start(BundleContext bundleContext) throws Exception {
HelloWorld helloWorld = new HelloWorld();
serviceRegistration = bundleContext.registerService(Hello.class, helloWorld, null);
}
public void stop(BundleContext bundleContext) throws Exception {
serviceRegistration.unregister();
}
}
Using an OSGi Service
public void start(BundleContext bundleContext) throws Exception {
ServiceReference reference = bundleContext.getServiceReference(Hello.class.getName());
Hello helloService = null;
if (reference != null) {
helloService = (Hello) bundleContext.getService(reference);
} else {
System.out.println("Service reference is null...");
}
if (helloService != null) {
System.out.println(helloService.sayHello());
} else {
System.out.println("Error...");
}
}
DEMO
o OSGi Services
o Sample Hello Service
o diag command to diagnose
o p command to check exports and
imports
http://www.slideshare.net/rossmason/realtime-apis
Handle Dynamism?
o Services can register/unregister at anytime.
o Service may not be available when tries to use the service
because of the startup order of bundles
o Somehow the service was acquired, but service get unregistered
and now we are having a stale service reference?
o Developer has to handle such scenarios?
Slate References
o Stale references are a result of an object either,
o A bundle which the class loader has stopped
o A service object which the unregistered
o Can be result in significant increase of memory
o Developer should follow the best practices to keep away from
slate references,
HOW?
o Listen to the relevant events and act accordingly.
Monitoring OSGi Services
o ServiceListener
o Service Trackers
o Declarative Services
ServiceListener
o A listener interface that can be used to capture service
lifecycle events.
public interface ServiceListener{
public void serviceChanged(ServiceEvent event);
}
o When an osgi service events are fired; will get a synchronous
callback to the serviceChanged(ServiceEvent event)
method
ServiceListener cntd...
public class SampleServiceListener implements ServiceListener , BundleActivator{
public void start(BundleContext bc) throws Exception {
bc.addServiceListener(this);
}
public void stop(BundleContext bc) throws Exception {
bc.removeServiceListener(this);
}
public void serviceChanged(ServiceEvent event) {
switch(event.getType()){
case ServiceEvent.REGISTERED:
break;
case ServiceEvent.UNREGISTERING:
break;
case ServiceEvent.MODIFIED:
break;
}
}
}
DEMO
o OSGi Service Listener
http://www.slideshare.net/rossmason/realtime-apis
ServiceListener cntd...
o Any concerns/issues regarding
the Service Listener approach?...
https://www.pinterest.com/salenka/meme-faces/
ServiceListener cntd...
o What if the service has registered
Before the service listener?
o You probably missed the Service
Registration event
Now What?....
https://www.pinterest.com/zmeers/meme-faces/
Working with OSGi Services
o Some major issues with listeners and trackers
o Memory Leaks
o Race conditions
o Working with OSGI services API complex and error prone
o Bundle developers tend to make optimistic assumptions regarding
the availability of services in an attempt to simplify their
code.
Declarative Services
o Alternative approach for OSGi Services API’s
o The bundle declare the services; it registers and acquires in an
xml file
o Less effort for developers
o Developers can focus more on the business logic, rather worrying
about the OSGi concerns.
Declarative Services cntd...
o Additional resources required in a bundle
o OSGI-INF/example.xml
o Framework reads the configuration file and enables the dynamism
o A service component contains a description that is interpreted at
run time to create and dispose objects
o Maven SCR Plugin to generate the OSGI-INF/example.xml
Sample Declarative Service
public class SampleServiceComponent {
private Hello hello;
protected void activate(ComponentContext context) { }
protected void deactivate(ComponentContext context) { }
public void setHelloService(Hello hello) {
this.hello = hello;
}
public void unsetHelloService(Hello hello) {
this.hello = null;
}
}
Sample Declarative Service -scrdescriptor
<?xml version="1.0" encoding="UTF-8"?>
<components>
<scr:component enabled="true" immediate="true" name="org.sample.sc.SampleServiceComponent">
<implementation class="org.sample.sl.SampleServiceComponent"/>
<property name="service.pid" value="org.sample.sc.SampleServiceComponent"/>
<reference name="org.sample.api.Hello"
interface="org.sample.api.Hello"
cardinality="1..1"
policy="dynamic"
target="(name=impl2)"
bind="setHelloService"
unbind="unsetHelloService"/>
</scr:component>
</components>
SCR Component Lifecycle
o SCR Component become satisfied if the following conditions are
satisfied,
o The component should be enabled
o All the component’s references are satisfied.
A reference is satisfied when,
1. The reference specifies optional cardinality or
2. There is at least one target service for the reference.
References to Services
o Cardinality
o 0..1 –> optional and unary
o 1..1 – mandatory and unary (Default)
o 0..n – optional and multiple
o 1..n – mandatory and multiple.
o Policy
o Static
o Dynamic
o Target
o Filter out the necessary services specifying a service property
DEMO
o Sample OSGi Service Component
o SCR JavaDoc Tags
o Maven SCR Plugin
o Troubleshoot issues with,
o ls command
o comp command
o Target property?
http://www.slideshare.net/rossmason/realtime-apis
Jar to Bundle Conversion
o Used to convert a Jar to Bundle
o Export all packages in jar file
o Export version is set to 0.0.0
o Added the DynamicImport-Package header
o No control over
o This is just evil :(
Jar to Bundle Conversion cntd...
o Hence introduced the WSO2 Orbit Project
o Just a pom.xml file with
o Proper dependencies
o Proper Information Hiding
o Most importantly with proper versions.
o Use the Maven-Bundle-Plugin to create orbit bundles
Best Practices
o Dynamism comes with the cost, so handle it properly
o Proper imports and exports
o Proper usage of versioning
o Manage the dependencies
o Use services when and where it requires
DEMO
o Annotation based SCR
o Sample Code , POM Config
o Enabling OSGI Debug Logs
http://www.slideshare.net/rossmason/realtime-apis
References
OSGi Alliance Specifications http://www.osgi.org/Specifications/HomePage
OSGI in Action - CREATING MODULAR APPLICATIONS IN JAVA
Carbon Documentation - https://docs.wso2.com/display/Carbon500/WSO2+Carbon+Documentation

OSGi Training for Carbon Developers

  • 1.
  • 2.
  • 3.
    Why Modularity o Easeof development (interactions are clearly defined) o Pluggable modules o Reusable modules
  • 4.
    Is Java providingthe modularity? o Compile time vs Runtime difference o Compiled and run under single/flat classpath o Alternatives o Write custom classloaders / non standard way to handle
  • 5.
  • 6.
    Java Compile Timevs Runtime... axiom-1.2.0.jar axis2-1.4.5.jar log4j.1.4.1..jar saxon.14.1..jar algpr.1.3.2..jar spring.0.2.1..jar spring-core.0.34.1..jar abdera_1.0.0..jar ajaxtags_1.3.0.beta-rc7-.jar annogen_0.1.0..jar antlr_3.2.0..jar apache-zookeeper_3.3.4..jar
  • 7.
    JAR (Java Archive) oDevelopment units in java o Application contains several jar files o At runtime there is no real meaning for a jar file o All the developed Jar files treated as a single, ordered, global list which is called the classpath.
  • 8.
    JAR (Java Archive)cntd.. o Problems with JAR Files - Multiple versions of JAR files cannot be loaded at same time - A JAR cannot declare dependencies on other JARs. - No mechanism for information hiding - Jars cannot be treated as modules. o Hence Java is suffering from modularity.. :(
  • 9.
    Dynamism in Java oCan a Jar file updated while the application is running? o Can new functionality be added while the application is running? (Update a class file with new version) o The application (JVM), needs to be restarted. o Java lacks Dynamism.
  • 10.
    OSGi for therescue? o Widely accepted way (A specification) of developing modular and dynamic systems using Java [1]. o OSGi Framework implementations (Open Source) o Equinox o Knopflerfish o Apache [1]. https://www.osgi.org/developer/specifications/
  • 11.
    Bundles o Bundles arethe development unit of OSGi o Typical OSGi application consists with multiple bundles o Bundles can share packages and hide packages in a consistent manner Most Importantly o What changes there in bundles, when comparing to JAR files?
  • 12.
    MANIFEST.MF o Use somestandard MANIFEST Headers. o Defines the bundle’s identity o Specifies the packages on which this bundle depends o Specifies the packages on which this bundle exports o Declares additional human-readable information Manifest-Version: 1.0 Bnd-LastModified: 1405099135557 Build-Jdk: 1.7.0_55 Built-By: aruna Bundle-Activator: org.sample.Activator Bundle-ManifestVersion: 2 Bundle-Name: sample Bundle-SymbolicName: sample Bundle-Vendor: WSO2 Inc Bundle-Version: 1.0.0 Created-By: Apache Maven Bundle Plugin Export-Package: org.sample;uses:="org.osgi.framework"; version="1.0.0" Import-Package: org.osgi.framework;version="[1.7,2)" Tool: Bnd-2.1.0.20130426-122213
  • 13.
    Bundles cntd.. o StandardJava - Place Jar files in classpath o OSGi Framework - Install bundles to framework
  • 14.
    Java class loadingwith OSGi...
  • 15.
  • 16.
    DEMO o OSGi Framework oFirst Look at a Sample Bundle o Try out the lifecycle events of a bundle http://www.slideshare.net/rossmason/realtime-apis
  • 17.
    Bundle Activator ManifestEntry o Bundle Activator Manifest Entry is the hook to the Bundle execution entry point. o Similar to the Main Method of a Jar file?.. o Header value specifies the name of a reachable class o Either a class in an Imported Package o A class in the Bundle class path o This class implements the org.osgi.framework.BundleActivator interface, and implements the following two methods. o Can use these two methods to customize the behaviours when the bundle is started and stopped. public interface BundleActivator { void start(org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception; void stop(org.osgi.framework.BundleContext bundleContext) throws java.lang.Exception; }
  • 18.
    Bundle Activator ManifestEntry cntd... o When the bundle installed and started, OSGi Framework creates an instance of Bundle Activator class and call the start() method. o When the bundle stop is initiated, OSGi Framework call the stop() method. o In practice when the stop is called, you should undo everything you did in the start method. o The activator instance on which start() is called is the same instance on which stop() is called. o The activator instance is discarded and isn’t used again, after stop() is called. o If the bundle is subsequently restarted after being stopped, a new activator instance is created, and the start() and stop() methods are invoked on it as appropriate.
  • 19.
    Bundle Context o Canbe accessed via start() and stop() of Bundle Activator class o Bundle context object is its role as the unique execution context of its associated bundle o Valid while the bundle is active. (The time range from the framework call start() up until to the stop() is called ) o Gain access to two types of methods o Related to deployment and lifecycle management. o Related to bundle interaction via services. o They should be treated as sensitive or private objects and not passed freely among bundles
  • 20.
    Listening for events oOSGi framework supports two types of events: BundleEvents and FrameworkEvents o The former event type reports changes in the lifecycle of bundles, whereas the latter reports framework-related changes o The BundleContext object has methods to register BundleListener and FrameworkListener objects for receiving BundleEvent and FrameworkEvent notifications, respectively o How to implement BundleListener and FrameworkListener in your code?. a. Create a new class which Implements BundleListener or FrameworkListener b. Implement the bundleChanged(BundleEvent) or frameworkEvent(FrameworkEvent) methods respectively. c. Register by creating a new Object of the implemented class to the BundleContext as a Listener using the bundleContext.addBundleListener() or bundleContext.addFrameworkListener() respectively. o No need to call the removeBundleListener() or removeFrameworkListener(), which will automatically removed when the bundle is stopped.
  • 21.
    Relationship between carbon& OSGi Non OSGi Portion OSGi Portion ./carbon.sh org.wso2.carbon.l auncher-5.2.0.jar Equinox + Some Carbon Bundles Bundles developed by Component Developers
  • 22.
    What about Dynamism? oAfter the Objects are instantiated, they will tightly coupled with the modules. o What if we want to change the module or part of the module, dynamically at the runtime?
  • 23.
    OSGi Services Layer oKind of in VM SOA model o OSGi Registry o OSGi Service is simply a Java Object published to the service registry o Services are published/looked up Using an exported interface. OSGi Service Registry Service Provider Service Consumer Publish Find
  • 24.
    Registering an OSGiService public class Activator implements BundleActivator { ServiceRegistration serviceRegistration; public void start(BundleContext bundleContext) throws Exception { HelloWorld helloWorld = new HelloWorld(); serviceRegistration = bundleContext.registerService(Hello.class, helloWorld, null); } public void stop(BundleContext bundleContext) throws Exception { serviceRegistration.unregister(); } }
  • 25.
    Using an OSGiService public void start(BundleContext bundleContext) throws Exception { ServiceReference reference = bundleContext.getServiceReference(Hello.class.getName()); Hello helloService = null; if (reference != null) { helloService = (Hello) bundleContext.getService(reference); } else { System.out.println("Service reference is null..."); } if (helloService != null) { System.out.println(helloService.sayHello()); } else { System.out.println("Error..."); } }
  • 26.
    DEMO o OSGi Services oSample Hello Service o diag command to diagnose o p command to check exports and imports http://www.slideshare.net/rossmason/realtime-apis
  • 27.
    Handle Dynamism? o Servicescan register/unregister at anytime. o Service may not be available when tries to use the service because of the startup order of bundles o Somehow the service was acquired, but service get unregistered and now we are having a stale service reference? o Developer has to handle such scenarios?
  • 28.
    Slate References o Stalereferences are a result of an object either, o A bundle which the class loader has stopped o A service object which the unregistered o Can be result in significant increase of memory o Developer should follow the best practices to keep away from slate references, HOW? o Listen to the relevant events and act accordingly.
  • 29.
    Monitoring OSGi Services oServiceListener o Service Trackers o Declarative Services
  • 30.
    ServiceListener o A listenerinterface that can be used to capture service lifecycle events. public interface ServiceListener{ public void serviceChanged(ServiceEvent event); } o When an osgi service events are fired; will get a synchronous callback to the serviceChanged(ServiceEvent event) method
  • 31.
    ServiceListener cntd... public classSampleServiceListener implements ServiceListener , BundleActivator{ public void start(BundleContext bc) throws Exception { bc.addServiceListener(this); } public void stop(BundleContext bc) throws Exception { bc.removeServiceListener(this); } public void serviceChanged(ServiceEvent event) { switch(event.getType()){ case ServiceEvent.REGISTERED: break; case ServiceEvent.UNREGISTERING: break; case ServiceEvent.MODIFIED: break; } } }
  • 32.
    DEMO o OSGi ServiceListener http://www.slideshare.net/rossmason/realtime-apis
  • 33.
    ServiceListener cntd... o Anyconcerns/issues regarding the Service Listener approach?... https://www.pinterest.com/salenka/meme-faces/
  • 34.
    ServiceListener cntd... o Whatif the service has registered Before the service listener? o You probably missed the Service Registration event Now What?.... https://www.pinterest.com/zmeers/meme-faces/
  • 35.
    Working with OSGiServices o Some major issues with listeners and trackers o Memory Leaks o Race conditions o Working with OSGI services API complex and error prone o Bundle developers tend to make optimistic assumptions regarding the availability of services in an attempt to simplify their code.
  • 36.
    Declarative Services o Alternativeapproach for OSGi Services API’s o The bundle declare the services; it registers and acquires in an xml file o Less effort for developers o Developers can focus more on the business logic, rather worrying about the OSGi concerns.
  • 37.
    Declarative Services cntd... oAdditional resources required in a bundle o OSGI-INF/example.xml o Framework reads the configuration file and enables the dynamism o A service component contains a description that is interpreted at run time to create and dispose objects o Maven SCR Plugin to generate the OSGI-INF/example.xml
  • 38.
    Sample Declarative Service publicclass SampleServiceComponent { private Hello hello; protected void activate(ComponentContext context) { } protected void deactivate(ComponentContext context) { } public void setHelloService(Hello hello) { this.hello = hello; } public void unsetHelloService(Hello hello) { this.hello = null; } }
  • 39.
    Sample Declarative Service-scrdescriptor <?xml version="1.0" encoding="UTF-8"?> <components> <scr:component enabled="true" immediate="true" name="org.sample.sc.SampleServiceComponent"> <implementation class="org.sample.sl.SampleServiceComponent"/> <property name="service.pid" value="org.sample.sc.SampleServiceComponent"/> <reference name="org.sample.api.Hello" interface="org.sample.api.Hello" cardinality="1..1" policy="dynamic" target="(name=impl2)" bind="setHelloService" unbind="unsetHelloService"/> </scr:component> </components>
  • 40.
    SCR Component Lifecycle oSCR Component become satisfied if the following conditions are satisfied, o The component should be enabled o All the component’s references are satisfied. A reference is satisfied when, 1. The reference specifies optional cardinality or 2. There is at least one target service for the reference.
  • 41.
    References to Services oCardinality o 0..1 –> optional and unary o 1..1 – mandatory and unary (Default) o 0..n – optional and multiple o 1..n – mandatory and multiple. o Policy o Static o Dynamic o Target o Filter out the necessary services specifying a service property
  • 42.
    DEMO o Sample OSGiService Component o SCR JavaDoc Tags o Maven SCR Plugin o Troubleshoot issues with, o ls command o comp command o Target property? http://www.slideshare.net/rossmason/realtime-apis
  • 43.
    Jar to BundleConversion o Used to convert a Jar to Bundle o Export all packages in jar file o Export version is set to 0.0.0 o Added the DynamicImport-Package header o No control over o This is just evil :(
  • 44.
    Jar to BundleConversion cntd... o Hence introduced the WSO2 Orbit Project o Just a pom.xml file with o Proper dependencies o Proper Information Hiding o Most importantly with proper versions. o Use the Maven-Bundle-Plugin to create orbit bundles
  • 45.
    Best Practices o Dynamismcomes with the cost, so handle it properly o Proper imports and exports o Proper usage of versioning o Manage the dependencies o Use services when and where it requires
  • 46.
    DEMO o Annotation basedSCR o Sample Code , POM Config o Enabling OSGI Debug Logs http://www.slideshare.net/rossmason/realtime-apis
  • 47.
    References OSGi Alliance Specificationshttp://www.osgi.org/Specifications/HomePage OSGI in Action - CREATING MODULAR APPLICATIONS IN JAVA Carbon Documentation - https://docs.wso2.com/display/Carbon500/WSO2+Carbon+Documentation