OSGi: The Lifecycle Layer. The Extender Pattern

Slides:



Advertisements
Similar presentations
AQute R4 By Peter Kriens CEO aQute OSGi Technology Officer and OSGi Fellow.
Advertisements

AQute Eclipse Environment By Peter Kriens CEO aQute OSGi Director of Technology and OSGi Fellow.
Introduce OSGi BlueDavy
CPSC 875 John D. McGregor Architecture evolution.
Component Models and Technologies Case Study: OSGI.
Radko Zhelev, IPP BAS Generic Resource Framework for Cloud Systems 1 Generic Resource Framework for Cloud Systems.
Apache Axis2 - OSGi Integration in WSO2 Carbon Platform
Remote Method Invocation Chin-Chih Chang. Java Remote Object Invocation In Java, the object is serialized before being passed as a parameter to an RMI.
OSGi: Open Services Gateway Initiative Richard Chapman 5 Sept
Presented by IBM developer Works ibm.com/developerworks/ 2006 January – April © 2006 IBM Corporation. Making the most of Creating Eclipse plug-ins.
OSGi: The Service Layer. The Whiteboard Pattern. Reading Ch.1: OSGi revealed Ch 2: Mastering modularity Ch 3: Learning lifecycle Ch 4: Studying services.
Spring Dynamic Modules. Startlocation: Documentation: /1.2.1/reference/html/
OSGi.
Chapter 10 Introduction to Components. Process Phases Discussed in This Chapter Requirements Analysis Design Implementation ArchitectureFramework Detailed.
Software Architecture for ColdFusion Developers Unit 4: Application Events and Global Variables.
EJB Framework.  As we know, EJB is the center of the J2EE architecture that provides a sturdy framework for building enterprise applications. The major.
LiveCycle Data Services Introduction Part 2. Part 2? This is the second in our series on LiveCycle Data Services. If you missed our first presentation,
OSGi & UPnP Technology 2009 Summer Ya-Lin Huang. 2 Outline What is OSGi Technology Introduction Alliance Specifications Key Benefits OSGi Framework Service.
Review: OSGi – a component framework for Java Bundle OSGi Framework Bundle Java Runtime Environment (JRE) Operating System (OS) Hardware “Dynamic Modules.
11 Web Services. 22 Objectives You will be able to Say what a web service is. Write and deploy a simple web service. Test a simple web service. Write.
Comparing JavaBeans and OSGi Towards an Integration of Two Complementary Component Models HUMBERTO CERVANTES JEAN-MARIE FAVRE 09/02.
In Pieces Breaking down monolithic applications with Spring-DM and OSGi.
Migrating Desktop The graphical framework for running grid applications Bartek Palak Poznan Supercomputing and Networking Center The.
OSGi Service Platform Open Service Gateway initiative.
Open Service Gateway Initiative (OSGi) Reporter : 林學灝 侯承育 1.
Slide 1 Extending Tuscany Raymond Feng Apache Tuscany committer.
Plug-In Architecture Pattern. Problem The functionality of a system needs to be extended after the software is shipped The set of possible post-shipment.
SWE 316: Software Design and Architecture Objectives Lecture # 18 Introduction to Components SWE 316: Software Design and Architecture To learn:  benefits.
Jaroslav Šnajberk, Tomáš Potužák, Richard Lipka Department of Computer Science and Engineering Faculty of Applied Sciences University of West Bohemia,
Dynamic Architectures (Component Reconfiguration) with Fractal.
CPSC 875 John D. McGregor Architecture evolution.
Introduction to Java Beans CIS 421 Web-based Java Programming.
Grid Computing Environment Shell By Mehmet Nacar Las Vegas, June 2003.
M1G Introduction to Programming 2 5. Completing the program.
Exceptions Chapter 16 This chapter explains: What as exception is Why they are useful Java exception facilities.
Slide 1 Extending Tuscany Raymond Feng Apache Tuscany committer.
Getting Started with the Open Services Gateway Initiative (OSGi) CNT 5517 Dr. Sumi Helal, Ph.D. Professor Computer & Information Science & Engineering.
Plug-in Architectures Presented by Truc Nguyen. What’s a plug-in? “a type of program that tightly integrates with a larger application to add a special.
Bulding a Modular Application with Coherence David Whitmarsh Independent Contractor Technical Architect Investment Banks
Introduction to OSGi +ActorFrame Surya Bahadur Kathayat
Plug-In Architecture Pattern. Problem The functionality of a system needs to be extended after the software is shipped The set of possible post-shipment.
ECLIPSE RICH CLIENT PLATFORM Part 1 Introduction.
Chapter 5 Introduction to Defining Classes Fundamentals of Java.
Today Advanced JavaFX animation and 3D demos from Oracle. Threading. Winter 2016CMPE212 - Prof. McLeod1.
Review of Last Year’s Midterm
Reference: Object Oriented Design and Programming (Horstmann)
CSE 501N Fall ‘09 21: Introduction to Multithreading
Overall Architecture and Component Model
Broker in practice: Middleware
Java Beans Sagun Dhakhwa.
Activities and Intents
Pre-assessment Questions
Application Development using Atlas Platform Sensor Network
Introduction to J2EE Architecture
Important terms Black-box testing White-box testing Regression testing
Intent (Thanks to Jim Fawcett for the slides)
Important terms Black-box testing White-box testing Regression testing
Phil Tayco Slide version 1.0 Created Oct 16, 2017
SwE 455 Tutorial.
Multithreaded Programming
Objectives In this lesson you will learn about: Need for servlets
Units with – James tedder
Units with – James tedder
Developing a Model-View-Controller Component for Joomla
Pre-assessment Questions
Applet Fundamentals Applet are small applications that are accessed on an Internet server, transported over the Internet, automatically installed and run.
Java Remote Method Invocation
Clients and Servers 19-Jul-19.
Clients and Servers 13-Sep-19.
Plug-In Architecture Pattern
Presentation transcript:

OSGi: The Lifecycle Layer. The Extender Pattern

Reading Ch.1: OSGi revealed Ch 2: Mastering modularity Ch 3: Learning lifecycle Ch 4: Studying services Ch 11: Component models and frameworks

Lifecycle Management Defines the bundle lifecycle operations : The lifecycle operations allow you to manage and evolve an application from its outside, by dynamically changing the composition of bundles inside a running framework. Defines how your bundles gain access to their execution context : Internal to an application, the lifecycle layer provides bundles with a way to interact with the OSGi framework and the facilities it provides at execution time.

OSGi Bundle Lifecycle

OSGI Console Most OSGi framework implementations have their own shells for interacting with a running framework Some OSGI Console commands: help List all available commands. ss List of all bundles together with their state and id. ss <string> List all bundles with names containing that string. start <id> Start up the bundle with a given id. stop <id> Stop the bundle with the given id. install <url> Install the bundle that the URL refers to. uninstall <id> Uninstall the bundle with the given id. diag <id> Show resolution problems for bundle with given id. exit

The System Bundle At execution time, the framework is represented as a bundle with an identifier of 0, called the system bundle. You don’t install the system bundle—it always exists while the framework is running. The system bundle follows the same lifecycle as normal bundles, so you can manipulate it with the same operations as normal bundles, but be careful ! Stopping the system bundle means shutting the system down.

The Bundle Cache When installing a bundle, the framework reads the bundle JAR file and saves a copy in a private area known as the bundle cache. This means two things: Installing a bundle into the framework is a persistent operation. After the bundle is installed, the framework no longer needs the original copy of the bundle JAR file. If you start an OSGi framework, install some bundles, shut down the framework, and then restart it, the bundles you installed will still be there in their original states In terms of your application, the bundle cache acts as the deployed configuration of the application. Your application’s configuration is the set of bundles you install into the framework

The Lifecycle Layer API The lifecycle layer API is composed of three main interfaces: BundleActivator, BundleContext, and Bundle. A BundleActivator is how a bundle hooks into the lifecycle layer to become lifecycle aware, The BundleContext represents the OSGi container, offers access to all framework facilities for inspecting and modifying the framework state at execution time. Each bundle has an associated Bundle object

Bundle Activator The bundle activator is a class implementing the org.osgi.framework.BundleActivator interface This interface provides the bundle with a hook into the lifecycle layer and the ability to customize what happens when it’s started or stopped. The framework knows about the activator of a bundle from its manifest file: the Bundle-Activator header specifies the class implementing the activator Not all bundles need an activator! An activator is necessary only if you’re creating a bundle and wish to specifically interact with OSGi API or need to perform custom initialization/de-initialization actions.

The BundleActivator Interface public interface BundleActivator { public void start(BundleContext context) throws Exception; public void stop(BundleContext context) throws Exception; } When the bundle is installed and started, the framework constructs an instance of the activator class and invokes the start() method. When the bundle is stopped, the framework invokes the stop() method. The activator instance on which start() is called is the same instance on which stop() is called. After stop() is called, the activator instance is destroyed. If the bundle is restarted after being stopped, a new activator instance is created !

Activator Example import org.foo.hello.Greeting; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { public void start(BundleContext ctx) { System.out.println("My Message - Started bundle Hello"); } public void stop(BundleContext ctx) { System.out.println("My Message - Stopped bundle Hello");

Example: Hello World Which bundle really needs an Activator ? org.foo.hello Greeting org.foo.hello import org.foo.hello.cli Client import Activator org.foo.hello.impl org.foo.hello.impl GreetingImpl Import org.osgi.*

Example: Hello World Which bundle really needs an Activator ? Not all bundles need an activator! The hello and hello.impl bundles are used in this scenario as simple libraries. They do not need activators. Still we may give them an activator (such as the one printing messages) The client bundle does not export anything; it needs an activator to start its activity. The start() method of the activator is acting as an entry point similar with a main() function.

ClientActivator (version 1) public class ClientActivator implements BundleActivator { private Greeting g=null; public void start(BundleContext context) throws Exception { g= new GreetingImpl(); System.out.println(g.sayHello()); } public void stop(BundleContext context) throws Exception { System.out.println("Greeting - stop"); The start() method must return quickly ! (because only after this the bundle is ACTIVE) Threads may be created and started here if needed ! All threads must be finished at stop().

ClientActivator (Version 2) public void start(BundleContext context) throws Exception { g=new GreetingImpl(); stop = false; new Thread(new Runnable() { public void run() { while (!stop) { try { Thread.sleep(8000); System.out.println(g.sayHello()); } catch (Exception e) {} } }).start(); public void stop(BundleContext context) throws Exception { stop = true;

The BundleContext Interface public interface BundleContext { ... String getProperty(String key); Bundle getBundle(); Bundle installBundle(String location, InputStream input) throws BundleException; Bundle installBundle(String location) throws BundleException; Bundle getBundle(long id); Bundle[] getBundles(); void addBundleListener(BundleListener listener); void removeBundleListener(BundleListener listener); void addFrameworkListener(FrameworkListener listener); void removeFrameworkListener(FrameworkListener listener); }

The Bundle Interface public interface Bundle { ... BundleContext getBundleContext(); long getBundleId(); Dictionary getHeaders(); Dictionary getHeaders(String locale); String getLocation(); int getState(); String getSymbolicName(); Version getVersion(); void start(int options) throws BundleException; void start() throws BundleException; void stop(int options) throws BundleException; void stop() throws BundleException; void update(InputStream input) throws BundleException; void update() throws BundleException; void uninstall() throws BundleException; }

BundleContext Example import org.foo.hello.Greeting; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; public class Activator implements BundleActivator { public void start(BundleContext ctx) { System.out.println("My Message - Started bundle Hello"); System.out.println("All the bundles in my context:"); Bundle[] bundles=ctx.getBundles(); for (Bundle b:bundles) { System.out.println(b.getBundleId()+" "+b.getSymbolicName()); } …

Listening for events The lifecycle layer API provides access to a lot of information, but it isn’t easy to poll for changes; it’s much more convenient if you can be notified when changes occur. To make this possible, the OSGi framework supports two types of events: BundleEvents and FrameworkEvents. The former event type reports changes in the lifecycle of bundles, whereas the latter reports framework-related issues. You can use the normal Java listener pattern in your bundles to receive these events. The BundleContext object has methods to register BundleListener and FrameworkListener objects for receiving BundleEvent and FrameworkEvent notifications, respectively.

Bundle events BundleEvent.INSTALLED BundleEvent.RESOLVED BundleEvent.STARTED BundleEvent.STOPPED BundleEvent.UPDATED BundleEvent.UNINSTALLED BundleEvent.UNRESOLVED

BundleListener Example class MyBundleListener implements BundleListener { public void bundleChanged(BundleEvent event) { System.out.println("Event type="+event.getType()+ " bundle"+event.getBundle()+ " source="+event.getSource()); } public class Activator implements BundleActivator { public void start(BundleContext ctx) { System.out.println("My Message - Started bundle Hello"); ctx.addBundleListener(new MyBundleListener()); …

The Extender Pattern The goal of the extender pattern is to achieve dynamically extensible applications. The technique of the extender pattern relies on exploiting the lifecycle events (installing, resolving, starting, stopping, etc) of other bundles and the feature of defining custom attributes in bundle metadata.

The Extender Pattern Typically, some bundle in the application acts as the extender: it listens for bundles being started and/or stopped. When a bundle is started, the extender probes it to see if it’s an extension bundle. The extender looks in the bundle’s manifest for specific metadata it recognizes. If the bundle does contain an extension, the extension is described by the metadata. The extender reads the metadata and performs the necessary tasks on behalf of the extension bundle to integrate it into the application. The extender also listens for extension bundles to be stopped, in which case it removes the associated extensions from the application.

Example: Hello World Dynamically Extensible Application The client must detect, during its runtime, if Greeting Extension bundles are activated and immediately use them If a Greeting Extension bundle is stopped the client will remove the extension A bundle is considered a Greeting Extension if: Its metadata contain the custom attributes GreetingExtensionName ExtensionClass It is expected that the extensionclass implements the interface Greeting

Example: Hello World Dynamically Extensible Application org.foo.hello Greeting Extension bundle org.foo.hello.impl1 MF GreetingImpl1

Example: Hello World Manifest file for EnglishGreeting Extension Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Implem1 Bundle-SymbolicName: org.foo.hello.implem1 Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.foo.hello.implem1.Activator Import-Package: org.foo.hello, org.osgi.framework;version="1.3.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Greeting-Extension-Name: EnglishGreeting Extension-Class: org.foo.hello.implem1.GreetingImpl1

Example: Hello World Manifest file for FrenchGreeting Extension Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Implem2 Bundle-SymbolicName: org.foo.hello.implem2 Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.foo.hello.implem2.Activator Import-Package: org.foo.hello, org.osgi.framework;version="1.3.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Greeting-Extension-Name: FrenchGreeting Extension-Class: org.foo.hello.implem2.GreetingImpl2

Example: Hello World Dynamically Extensible Application org.foo.hello Greeting org.foo.hello import org.foo.hello.cli org.foo.hello.impl1 Client Activator GreetingImpl1 org.foo.hello.impl2 GreetingImpl1 MF GreetingImpl2 Import org.osgi.*

Example: Hello World Dynamically Extensible Application Applying the Extender Pattern: The client registers GreetingListener - a BundleListener listening for BundleEvent.STARTED and BundleEvent.STOPPED events When receiving the event notification, it will probe if the bundle that generated it is a Greeting Extension (by inspecting its metadata for the ExtensionName attribute) If the event was not generated by an extension bundle, ignore it If the bundle is an extension bundle that has to be added: Inspect metadata to know the value of the ExtensionClass attribute Request the bundle to load the extension class and instantiate it via reflection The client will get the instantiated object and use it via the Greeting interface

public class GreetingListener implements BundleListener { private GreetingSet m_gs = null; public GreetingListener(GreetingSet gs) { m_gs = gs; } public void bundleChanged(BundleEvent event) { … private boolean isExtension(Bundle bundle) { private void addExtension(Bundle bundle) { private void removeExtension(Bundle bundle) {

GreetingListener::bundleChanged public void bundleChanged(BundleEvent event) { System.out.println("Listener: Event type=" + event.getType() + " bundle“ + event.getBundle() + " source=" + event.getSource()); Bundle bundle = event.getBundle(); if (event.getType() == BundleEvent.STARTED) { if (isExtension(bundle)) addExtension(bundle); } if (event.getType() == BundleEvent.STOPPED) { removeExtension(bundle);

GreetingListener::isExtension private boolean isExtension(Bundle bundle) { Dictionary dict = bundle.getHeaders(); // Try to get the name of the extension. String name = (String) dict.get(“Greeting-Extension-Name”); // Return immediately if the bundle is not an extension. if (name == null) { System.out.println("Bundle " + bundle.getSymbolicName() + " not a Greeting Extension"); return false; } + " is a Greeting Extension"); return true;

GreetingListener::addExtension private void addExtension(Bundle bundle) { System.out.println("Greeting extension will be added: " + bundle.getSymbolicName()); Dictionary dict = bundle.getHeaders(); String name = (String) dict.get(“Greeting-Extension-Name”); // Get the class of the extension. String className = (String) dict.get(“Extension-Class”); Class clazz = null; try { clazz = bundle.loadClass(className); m_gs.addGreeting(name, (Greeting) clazz.newInstance()); } catch (Exception e) { e.printStackTrace(); }

ClientActivator::start public void start(BundleContext context) throws Exception { stop = false; m_gs = new GreetingSet(); context.addBundleListener(new GreetingListener(m_gs)); new Thread(new Runnable() { public void run() { while (!stop) { try { Thread.sleep(8000); String text = ""; for (Object g : m_gs.getAllGreetings()) { text = text + " " + ((Greeting) g).sayHello(); } System.out.println(text); } catch (Exception e) {} }).start();

Summary A bundle can only be used by installing it into a running instance of the OSGi framework. The framework associates a lifecycle state with each installed bundle The lifecycle layer API is composed of three main interfaces: BundleActivator, BundleContext, and Bundle. A BundleActivator is how a bundle hooks into the lifecycle layer to become lifecycle aware, which allows it to gain access to all framework facilities for inspecting and modifying the framework state at execution time. Monitoring bundle lifecycle events is a form of dynamic extensibility available in the OSGi framework based on the dynamically changing installed set of bundles (also known as the extender pattern).