Presentation is loading. Please wait.

Presentation is loading. Please wait.

aQute Bundle Programming By Peter Kriens CEO aQute OSGi Director of Technology & OSGi Fellow.

Similar presentations


Presentation on theme: "aQute Bundle Programming By Peter Kriens CEO aQute OSGi Director of Technology & OSGi Fellow."— Presentation transcript:

1

2 aQute Bundle Programming By Peter Kriens CEO aQute OSGi Director of Technology & OSGi Fellow

3 ©1999-2004 aQute, All Rights Reserved slide #2 Contents Overview The Bundle Class loading Using Services Threads and synchronization Cleaning up Whiteboard pattern Life Cycle Operations XML Parsing Tools

4 ©1999-2004 aQute, All Rights Reserved slide #3 Bundle Programming Overview So you have to start programming for OSGi? Assuming you have some experience with J2SE programming, what are the key differences? –Dynamic environment, everything changes all the time –You share code and resources with other applications –Many bundles run on resource constrained devices Programming in a dynamic environment is difficult The course first goes through the gory details and then shows some convenience models that are coming in R4

5 ©1999-2004 aQute, All Rights Reserved slide #4 The bundle A bundle is a JAR file –Based on the ZIP format, contains Classes Resources (images,files) Manifest A bundle contains all that is necessary to run it, except some well defined dependencies

6 ©1999-2004 aQute, All Rights Reserved slide #5 Bundle model Bundles are like the (old) Mac model, not like the PC model A single file contains all that is needed No requirement for application installers that modify data all over the place Subsystems access the bundle to provide the relevant information they need No uninstallers that leave remains Web Server Desk Top Data Base Mac Application PC Application

7 ©1999-2004 aQute, All Rights Reserved slide #6 Bundle Model For example, a management system wants to use an icon for a bundle They agree on a common name for a gif resource in the JAR file (the icon) If the management system receives the JAR it can find the icon and display System is easy to extend independent from others, only the JAR namespace must be managed Management System Bundle META-INF MANIFEST.MF icon.gif com/acme/appl/… … Get META-INF/icon.gif Display icon

8 ©1999-2004 aQute, All Rights Reserved slide #7 Bundle Model Most important resources are the classes Classes in Java are packed in packages Each package is a directory in the JAR file –Dots become / however Naming, by convention, is done with the reverse domain name –com.acme.application Package naming is important for versioning an dependencies Never program in the default package (i.e. no package name specified) com.acme.application javax.servlet javax.servlet.http META-INF MANIFEST.MF com/acme/application MyApplication.class smiley.gif Handler.class javax/servlet Servlet.class ServletRequest.class javax/servlet/http …

9 ©1999-2004 aQute, All Rights Reserved slide #8 Manifest The Manifest contains information about the bundle and its resources The Manifest is standardized by SUN –http://java.sun.com/docs/books/tutorial/j ar/basics/manifest.htmlhttp://java.sun.com/docs/books/tutorial/j ar/basics/manifest.html –http://java.sun.com/j2se/1.3/docs/guide/j ar/jar.htmlhttp://java.sun.com/j2se/1.3/docs/guide/j ar/jar.html The basic format is –Header –: –Value (max 76 characters but is extended on the next line if the next line starts with a space) A valid manifest starts with –Manifest-Version: 1.0 Headers are not case sensitive Java 2 has a Manifest parser in the java.util.jar package

10 ©1999-2004 aQute, All Rights Reserved slide #9 Interesting OSGi headers Bundle-Activator –The fully qualified name of a class that is used to start the bundle Bundle-Name –Human Readable name, used to in UIs Bundle-SymbolicName –Name of the application that this bundle implements. The symbolic name must remain the same, but the version may change Bundle-Version –The actual version of the bundle. [. [. [. ]]] Bundle-Vendor Bundle-Copyright Bundle-Category Bundle-Description

11 ©1999-2004 aQute, All Rights Reserved slide #10 Starting the bundle There are two types of bundles –Applications –Libraries Applications require the activation of the bundle, libraries only export packages The manifest header Bundle-Activator points to a fully qualified class name –com.acme.application.Activator This class must implement the org.osgi.framework.BundleActivator interface org.osgi.framework.BundleActivator When using Eclipse, the browse button in the manifest header will analyze the classes to find out which classes implement this interface

12 ©1999-2004 aQute, All Rights Reserved slide #11 Starting the bundle The start method from the BundleActivator interface must be implemented carefully The start method borrows a Framework thread that is shared between all bundles. The start method should therefore return quickly Programmers do heavy initialization in the start method and the start method is synchronous and sequential A start method does not get its own thread!

13 ©1999-2004 aQute, All Rights Reserved slide #12 Initialization Number one problem in OSGi deployments is startup time … Initialization should be limited to setting up the minimum and doing the rest of the initialization when the functionality is really needed –Lazy initialization is best, maybe your function is never needed! –Heavy initialization should be done in a thread Dangerous functions are –Opening connections (name lookup can take serious time) –Allocating resources that are not yet needed –Waiting for events that can take time to happen

14 ©1999-2004 aQute, All Rights Reserved slide #13 The BundleContext The start method hands over a org.osgi.framework.BundleConte xt object org.osgi.framework.BundleConte xt This object represents the Framework but each bundle will gets own private context BundleContext objects should not be shared –Cost allocation –Capability The Framework is the center of the OSGi service platform universe Bundle A Frame work Bundle B Bundle C Bundle Context

15 ©1999-2004 aQute, All Rights Reserved slide #14 Bundle Context method categories Private File Access Service Registry Event Handling Life Cycle Management Status information More about this later …

16 ©1999-2004 aQute, All Rights Reserved slide #15 Sharing packages The Hello World example was trivial because it was fully self contained –It did not use any external resources –Nor did it provide any Real world applications share code and interact with each other Bundles can come and go at will, this introduces difficult sharing problems –What will happen when shared package goes away? –What happens when a new version becomes available? The Framework handles these issues

17 ©1999-2004 aQute, All Rights Reserved slide #16 Sharing packages All classes in the bundle are by default private Sharing of classes is done with packages Manifest headers are used to control the sharing Import-Package contains a list of packages that are needed before this bundle can run –Import-Package: com.acme.application, com.acme.event, javax.servlet Bundle B Framework Import-Package

18 ©1999-2004 aQute, All Rights Reserved slide #17 Sharing packages Export-Package contains a list of packages that may be shared with other bundles –Export-Package: com.acme.xyz, javax. All packages that are referred to from a bundle must be imported except ones that start with java. This said, there is an issue that currently packages on the classpath must not be imported or they cannot be found. This may change in the future Bundle A Bundle B Framework Import-Package Export-Package

19 ©1999-2004 aQute, All Rights Reserved slide #18 Class cast exception The Framework guarantees that each package has only a single provider by picking only one provider, even if there are multiple exporters Why is it important that all bundles use the same class object? If the same class occurs multiple times in the system, bundles will experience hard to trouble shoot ClassCastExceptions because the names of the classes are equal So the Framework prevents this case MyObject x = (MyObject) z; Bundle A Bundle B B Provides the MyObjectClass But z is from the class MyObject from A

20 ©1999-2004 aQute, All Rights Reserved slide #19 Package sharing AB C Private classes Shared classes Framework guarantees single Exporter for each package

21 ©1999-2004 aQute, All Rights Reserved slide #20 Package versions When a package is imported or exported, it may have a version –Import-Package: com.acme.application;specification-version=3.1 –Export-Package: com.acme.application;specification-version=3.5 You may both import and export a package with different versions –Try to explain why export should have a higher version number? Packages must be backward compatible with lower version numbers When the specification-version attribute is omitted, the Framework assumes a version that is less than 0.0.0

22 ©1999-2004 aQute, All Rights Reserved slide #21 Standard libraries and versions Many standard libraries are not well versioned, if at all Even if they are, they do not have the OSGi headers This means they should normally be imported without version specifiers

23 ©1999-2004 aQute, All Rights Reserved slide #22 R4 And Versions R4 will have a more rich version model as well as standardizing the version syntax –Supported by a Version object Import can be specified with ranges, no longer requiring the backward compatibility rules R4 will also allow sharing of bundles –Enables private package sharing between bundles –Means same package name can appear in the system in different versions

24 ©1999-2004 aQute, All Rights Reserved slide #23 Resolving Before a bundle is started, it must be resolved Resolving tries to match imports and exports If a bundle is resolved, it may be started Resolving may happen at any time between the installation and start Starting the bundle must attempt to resolve the bundle

25 ©1999-2004 aQute, All Rights Reserved slide #24 Resolving Bundle A Export org.osgi.service.log com.ibm.service.log com.ibm.j9 Import org.osgi.service.http javax.servlet.http Framework org.osgi.framework org.osgi.service.http Bundle B Export ericsson.osgi javax.servlet javax.servlet.http org.osgi.service.log Import org.osgi.service.http B resolved A resolved

26 ©1999-2004 aQute, All Rights Reserved slide #25 Dynamic Importing Static import (Import-Package) allows tool to reason about the bundle before it is installed Sometimes the packages that need to be imported are not known a- priori This only possible with the Class.forName mechanism Many popular packages use Class.forName to bind to unknown providers –Ant tasks –Jave Media Framework plugins –Applets –Security Providers Normal compiled implies that the dependency is always known a priori Tools can take advantage of this a priori knowledge and create the appropriate import statements

27 ©1999-2004 aQute, All Rights Reserved slide #26 Assignment: Playing with Import and Export Use the Hello World project to see the effects of importing and exporting Add an import clause to the manifest of hello world –Import-Package: org.osgi.framework Create the JAR and check the console The bundle should start OK

28 ©1999-2004 aQute, All Rights Reserved slide #27 Cheating Note that we actually cheated in the Eclipse tutorial, we never imported org.osgi.framework, but we should have It works because the org.osgi.framework package is also on the system class path In officially is required to import org.osgi.framework though … in R4 code that does not import correctly will break

29 ©1999-2004 aQute, All Rights Reserved slide #28 Assignment: Playing with Import and Export Modify the manifest to add a version of 99 to the import statement –Import-Package: org.osgi.framework;specification -version=99 Build and check again Now move back to version 1 Check again

30 ©1999-2004 aQute, All Rights Reserved slide #29 Assignment: Playing with Import and Export

31 ©1999-2004 aQute, All Rights Reserved slide #30 What happens when we use a class we do not import? Make a copy of HelloWorld, call it UsingImportedClass Extend HttpServlet (Use Control-Shift-O to find the imports) Change the manifest so it points to our new UsingImportedClass Create the bundle See the error message on the bottom of the console The framework cannot find the java.servlet.http package

32 ©1999-2004 aQute, All Rights Reserved slide #31 How do we solve this? Create an import statement in the manifest for –javax.servlet –javax.servlet.http Both are needed because javax.servlet.http.HttpServlet extends javax.servlet.Servlet … Manifest-Version: 1.0 Bundle-Activator: aQute.workshop.hello.UsingImportedClass Import-Package: org.osgi.service.log;specification- version=1.2, javax.servlet;specificaton-version=2.1, javax.servlet.http; specificaton-version=2.1

33 ©1999-2004 aQute, All Rights Reserved slide #32 How can we get the ClassCastException? This is something you (normally) want to avoid at all times! However, it is educational to see how it can be done. The ClassCastException can happen when: –You have a class in your JAR, say X –You get an object from elsewhere that is of class X –You assign this object to a variable of type X

34 ©1999-2004 aQute, All Rights Reserved slide #33 How to get a class cast exception We can show this using services (which will be thoroughly discussed later) We will get the log service from the Framework We will also include the org.osgi.service.log package into our JAR By using 2 different manifests we select where the log comes from HelloWorld.jar osgi.jar...service.log aQute.hello...service.log …

35 ©1999-2004 aQute, All Rights Reserved slide #34 Class Cast Exception package aQute.workshop.hello; import org.osgi.framework.*; import org.osgi.service.log.*; public class ClassCastException implements BundleActivator { public void start(BundleContext context) throws Exception { System.out.println("ClassCastException Example"); ServiceReference ref = context.getServiceReference(LogService.class.getName()); Object object = context.getService(ref); try { LogService log = (LogService) object; System.out.println("We could succesfully cast the log service... "); } catch( Exception cce ) { System.out.println("We could not cast the log service... "); } System.out.println( "Classloader we see: " + LogService.class + " " + LogService.class.getClassLoader() ); Class [] interfaces = object.getClass().getInterfaces(); for ( int i = 0; i<interfaces.length; i++ ) { System.out.println( "Their classloader " + interfaces[i] + " " + interfaces[i].getClassLoader() ); } public void stop(BundleContext arg0) throws Exception { System.out.println("Goodbye ClassCastException");} }

36 ©1999-2004 aQute, All Rights Reserved slide #35 HelloWorld Log Service Class Cast Exception Manifest 1 (different classloaders) Manifest-Version: 1.0 Bundle-Activator: aQute.workshop.hello.ClassCastException Import-Package: org.osgi.framework; specification- version=1 Manifest 2 (importing, assuring same classloader) Manifest-Version: 1.0 Bundle-Activator: aQute.workshop.hello.ClassCastException Import-Package: org.osgi.framework; specification- version=1, org.osgi.service.log;specification-version=1.2 org.osgi.service.log aQute.workshop.hello org.osgi.service.log org.osgi.impl.service.log … object variable Ouch… OK

37 ©1999-2004 aQute, All Rights Reserved slide #36 What Did This Assignment Teach? Bundles have dependencies on other classes that must be fulfilled before the bundle can be resolved Resolved bundles can be started It is necessary to specify all imports except java.* Class cast exceptions are hard to debug!

38 ©1999-2004 aQute, All Rights Reserved slide #37 Bundle Class path There is a special manifest header that is called Bundle- Classpath This contains a comma separated list of embedded JAR files –. is the JAR itself –Bundle-Classpath:.,servlet.jar The Framework will treat the JAR file according to this Bundle classpath –Including order Powerful way to include existing JAR files without having to break them open main.jar b.jar c.jar a.jar Bundle-Classpath:.,a.jar, b.jar,c.jar

39 ©1999-2004 aQute, All Rights Reserved slide #38 Collaborative model The OSGi specifications are more than an Applet, MIDlet, Xlet runner These models access APIs through shared packages –Factories –Listeners This model is supported in OSGi, but there are some disadvantages to this model –Packages need to be resolved at bundle start time, hard, if not impossible, to add missing packages later –No notifications for packages that come and go –Difficult to model multiplicity –Java can eagerly bind linked packages –Classloading issues

40 ©1999-2004 aQute, All Rights Reserved slide #39 Collaborative Model What is needed is a controlled facility to communicate with other bundles The OSGi Alliance therefore introduced the service registry The service registry allows bundles to register objects through which they can communicate Other bundles can find these objects, or get notifications when they are registered or unregistered Framework fully manages this collaboration –Dependencies –security

41 ©1999-2004 aQute, All Rights Reserved slide #40 Bundle Collaborative model JAVA Operating System Hardware OSGi Framework Service registry packages

42 ©1999-2004 aQute, All Rights Reserved slide #41 Collaborative model How does OSGi relate to MIDP, Java TV, Browsers JAVA Operating System Hardware Java Application Manager Service registry packages Midlet, Xlet, or Applet Midlet, Xlet, or Applet No native code No package management (versions!) No collaboration No management bundles

43 ©1999-2004 aQute, All Rights Reserved slide #42 Service Specifics A service (in the OSGi sense) is an object registered with the Framework for communicationwith other bundles The semantics and syntax of a service are specified in a Java interface Services can be seen as ports on the bundle service

44 ©1999-2004 aQute, All Rights Reserved slide #43 A Service Defined Object that implements a Java Interface register get events: REGISTERED, UNREGISTERING, MODIFIED

45 ©1999-2004 aQute, All Rights Reserved slide #44 Real World Example

46 ©1999-2004 aQute, All Rights Reserved slide #45 Services and Interfaces Bundle Service Registry listen Display public void show(String msg) { System.out.println(msg); } public void show(String msg) { } public void show(String msg) { file.write(msg.getBytes()); } B C register Display public interface Display { void show(String msg); } A

47 ©1999-2004 aQute, All Rights Reserved slide #46 Services continued Different bundles (from different vendors) can implement the same interface –Implementation is not visible to clients –Allows operator to replace implementations without disrupting service Services are (optionally) registered with properties –Describe information about the service –The client can search (or listen) for services that have certain properties and values for properties Standard properties –objectclassThe interfaces of the service –service.idSystem generated unique id –service.pidPersistent id –service.rankingOrdering value

48 ©1999-2004 aQute, All Rights Reserved slide #47 Services The service model enables a powerful component model Components can be plugged in, and removed, as needed The system adapts to these changing configurations

49 ©1999-2004 aQute, All Rights Reserved slide #48 Services API Service objects should not be freely shared because of security and performance issues Therefore, services are normally manipulated with a ServiceReference object A ServiceReference can –Provide the properties of the service –Be freely passed as a parameter to other bundles –Can be used to retrieve the actual service via the BundleContext, which might be personalized Client Code Service Reference Real Service Object Bundle Context getService(ServiceReference) getServiceReference(…)

50 ©1999-2004 aQute, All Rights Reserved slide #49 How to get Services First is to obtain a Service Reference Simplest way is the one that picks the highest ranking service –ServiceReference getServiceReference(String ifName) The parameter is the name of the interface that is required –A good practice is to use MyClass.class.getName() instead of com.acme.mypackage.MyClass because it will be automatically changed when you refactor The associated service is guaranteed to implement this interface (the package of the interface must be imported) Ranking is defined by properties –service.ranking –service.pid

51 ©1999-2004 aQute, All Rights Reserved slide #50 Using getServiceReference A Service Reference is a handle to the service Example code LogServicelog; public void start(BundleContext context) throws Exception { ServiceReference ref = context.getServiceReference( LogService.class.getClass() ); if ( ref != null ) { log = (LogService) context.getService(ref); }

52 ©1999-2004 aQute, All Rights Reserved slide #51 Access to Service Reference Properties The Service Reference object holds a number of properties –Object getProperty(String key) –String [] getPropertyKeys() Properties can be any standard Java object, including arrays, vectors, arrays of primitives, etc. Filter searches expand arrays. –X = [a,b], matches (x=a) and (x=b) It is also possible to find all the keys –String[] getPropertyKeys();

53 ©1999-2004 aQute, All Rights Reserved slide #52 Assignment Write a bundle that displays the Log Service properties on the console –Get the reference to the log service –Get the keys from this references –For each key Get the value Print the key=value For nicety, printout arrays separately!

54 ©1999-2004 aQute, All Rights Reserved slide #53 Access to the Associated Bundles Service References are associate with a registering bundle and a number of bundles that use it –Bundle getBundle(); –Bundle[] getUsingBundles(); Note null return for getUsingBundles() Bundle A Bundle B Bundle C getUsingBundles getBundle

55 ©1999-2004 aQute, All Rights Reserved slide #54 Getting Services It is possible to get all Services –ServiceReference[] getServiceReferences( String ifName, String filter) Note potential null return The ifName is the same as the previous but in this case it may be null The second parameter is a filter specification The filter syntax is of small expressive language that does an assertion on the properties

56 ©1999-2004 aQute, All Rights Reserved slide #55 Filter Language The syntax is based on simple to parse, recursive structure Supported expressions –And (& expr+ ) –Or (| expr+) –Not (!expr+) –Simple(property-keyopliteral )

57 ©1999-2004 aQute, All Rights Reserved slide #56 Filter Syntax Operations –=equals (may contain * for wildcards) –~=looks like –>=Greater than or equal –<=Less than or equal –=*Is defined Examples –(vendor=*IBM*) –(&(service.pid=com.acme.bananas)(priority>=10)) –(url=*)

58 ©1999-2004 aQute, All Rights Reserved slide #57 getServiceReferences Example code class MyService { void foo(); } public void start(BundleContext context) throws Exception { ServiceReference ref[] = context.getServiceReferences( MyService.class.getName(), (url=*) ); for ( int i= 0; ref!= null && i<ref.length; i++ ) { MyService mys = context.getService(ref[i]); mys.foo(); } }

59 ©1999-2004 aQute, All Rights Reserved slide #58 Assignment: Printout all services Create a bundle that prints out all the services that have the property service.pid Print: –Their properties –The bundle that registered it –The bundles that are using it

60 ©1999-2004 aQute, All Rights Reserved slide #59 Registering a service There are two calls on the Bundle Context to register a service, both return a Service Registration object –ServiceRegistration registerService(String ifName, Object service, Dictionary properties ) –ServiceRegistration registerService(String ifNames[], Object service, Dictionary properties ) The ifName must match an interface on the service object The service is immediately available to other bundles The service can be unregistered with the unregister method on the Service Registration The properties of the service can also be changed with the setModified(Dictionary) call

61 ©1999-2004 aQute, All Rights Reserved slide #60 Registering a Service import org.osgi.framework.*; import org.osgi.service.cm.*; public class RegisterService implements BundleActivator { class MyManagedService implements ManagedService { public void updated(Dictionary properties) throws ConfigurationException { System.out.println("Updated " + properties); } public void start(BundleContext context) throws Exception { System.out.println("Register Service Example"); Hashtable properties = new Hashtable(); properties.put("service.pid", "biz.aQute.ExamplePid"); ServiceRegistration reg = context.registerService(ManagedService.class.getName(), new MyManagedService(), properties); } public void stop(BundleContext arg0) throws Exception { }

62 ©1999-2004 aQute, All Rights Reserved slide #61 Registering a Service In the monitor you can see the registration of the service

63 ©1999-2004 aQute, All Rights Reserved slide #62 Listening to services It is possible to get notifications of –REGISTERED Service registrations –MODIFIEDService modifications –UNREGISTEREDService unregistrations All you have to do is add a listener to the BundleContext, there are 2 versions –addServiceListener(ServiceListener) –addServiceListener(ServiceListener,String filter) The second version allows to filter for only the services that are needed Service Listening is synchronous –Potential for deadlocks

64 ©1999-2004 aQute, All Rights Reserved slide #63 Listening to Services public class ServiceListening implements BundleActivator, ServiceListener { public void serviceChanged(ServiceEvent event) { Stringtype= "UNKNOWN"; switch (event.getType()) { case ServiceEvent.MODIFIED :type = "MODIFIED"; break; case ServiceEvent.REGISTERED : type = "REGISTERED"; break; case ServiceEvent.UNREGISTERING : type = "UNREGISTERING"; break; } ServiceReference ref = event.getServiceReference(); Long id = (Long) ref.getProperty("service.id"); String [] classes = (String[]) ref.getProperty("objectclass"); System.out.println( "Service Event "+type + ":" + id + ":" + classes[0]); } public void start(BundleContext context) throws Exception { System.out.println("Listening to Services Example"); context.addServiceListener(this); } public void stop(BundleContext arg0) throws Exception { }

65 ©1999-2004 aQute, All Rights Reserved slide #64 Assignment: Listenening Listen to service events Print them out Use the monitor to stop/start the bundles to see that they generate service events by registering and unregistering services

66 ©1999-2004 aQute, All Rights Reserved slide #65 Service Registry The Framework Service Registry is available to all bundles to collaborate with other bundles Requires permission –Under Operator control Services are associated with properties –Query language to find appropriate service Bundles can update the properties

67 ©1999-2004 aQute, All Rights Reserved slide #66 Service Factories How does a bundle customize a service per bundle? The ServiceFactory interface allows a bundle to return a specific customized service object for each bundle Framework calls back the factory for service get and unget methods The Framework keeps a reference count to the service Get and Unget will be perfectly matched

68 ©1999-2004 aQute, All Rights Reserved slide #67 Service Factories Framework Bundle Standard Bundle Factory Bundle A { } Bundle B { }

69 ©1999-2004 aQute, All Rights Reserved slide #68 Assignment: ServiceFactory Copy HelloWorld to ServiceFactoryExample Register a ServiceFactory for a String object as service type Register it with the following attributes –type=grabme –times=new Integer(5) Let the ServiceFactoryExample also implement the ServiceFactory interface Implement the getService(Bundle, ServiceRegistration) to return a unique string that also includes the calling bundles location Print out the get operation Print out the unget operation

70 ©1999-2004 aQute, All Rights Reserved slide #69 Create a test bundle Copy HelloWorld to Grabber Listen to all services that have the property –type=grabme If a REGISTERED event happens –Get the times propery (an Integer) –Get the service times times –Print out the service Copy hello.jardesc to grabber.jardesc Copy Manifest.mf to grabber.mf Modify the manifest to have the Bundle Activator point to the Grabber In the context menu of the grabber.jardesc file select Open JAR Packager Update the location of the jar descriptor file as well as the manifest Finish

71 ©1999-2004 aQute, All Rights Reserved slide #70 Service Tracker Services register and unregister all the time Onus on the programmer to only use services that are registered ServiceTracker simplifies this task: –Maintains a list of active services –Events can be overridden in subclass Used in almost every bundle

72 ©1999-2004 aQute, All Rights Reserved slide #71 Service Tracker Use "As is" Gets each service from the registry when it is available –Object getService() –Object[] getServices() –Object waitForService()

73 ©1999-2004 aQute, All Rights Reserved slide #72 ServiceTracker Track all services of a certain type in the service registry Use subclassing a ServiceTracker or use the ServiceTrackerCustomizer interface Implement the methods: –Object addingService(ServiceReference r) –void modifiedService(ServiceReference r, Object service) –void removedService(ServiceReference r, Object service)

74 ©1999-2004 aQute, All Rights Reserved slide #73 Create a service tracker A service tracker requires a Bundle Context Notice that after creation, it needs to be opened public void start(BundleContext context) throws Exception { System.out.println("ListServices"); tracker = new ServiceTracker( context, context.createFilter("(service.pid=*)"), null ) { public Object addingService(ServiceReference ref) { printServiceReference(ref); return ref; } public void removedService(ServiceReference ref, Object o) { } }; tracker.open(); }

75 ©1999-2004 aQute, All Rights Reserved slide #74 ServiceTracker: create Framework Bundle A Bundle B Bundle C

76 ©1999-2004 aQute, All Rights Reserved slide #75 ServiceTracker: open Framework Bundle A Bundle B Bundle C addServiceListener Object addingService(ServiceReference r){…}

77 ©1999-2004 aQute, All Rights Reserved slide #76 ServiceTracker: adding Framework Bundle A Bundle B Bundle C addServiceListener Object addingService(ServiceReference r){…}

78 ©1999-2004 aQute, All Rights Reserved slide #77 ServiceTracker: removing Framework Bundle A Bundle B Bundle C addServiceListener void removedService(ServiceReference r,Objecto){…}

79 ©1999-2004 aQute, All Rights Reserved slide #78 ServiceTracker: modified Framework Bundle B Bundle C addServiceListener void modifiedService(ServiceReference r, Object o){…} Bundle A ServiceTrackerList

80 ©1999-2004 aQute, All Rights Reserved slide #79 Multiple constructors First is used to create a tracker on a specific interface –ServiceTracker( BundleContext, String, ServiceTrackerCustomizer) Second constructor is used to create a tracker with a filter Filters can be created with the BundleContext –ServiceTracker( BundleContext, Filter, ServiceTrackerCustomizer) Either constructor can use a ServiceTrackerCustomier When the customizer is null, the ServiceTracker will call the methods on itself, allowing subclassing The service tracker only becomes active after it is opened It should be closed in the stop() method

81 ©1999-2004 aQute, All Rights Reserved slide #80 Assignment In a previous assignment we listed all the services that had a service.pid attribute Change this example to use a service tracker instead

82 ©1999-2004 aQute, All Rights Reserved slide #81 Dependencies The Framework manages the dependencies between bundles Bundles that are installed and started will register services Framework will automatically unregister services when a bundle stops Event notifications for all important events

83 ©1999-2004 aQute, All Rights Reserved slide #82 Dependencies Framework Bundle C { } Bundle A { } Bundle B { } Install A start events: install events: register

84 ©1999-2004 aQute, All Rights Reserved slide #83 Framework Dependencies Bundle C { } Bundle B { } Uninstall stop events: uninstall events: unregister Bundle A { }

85 ©1999-2004 aQute, All Rights Reserved slide #84 Dependency Management When a bundle stops, it is cleaned up –Registered services are removed –References to other services removed Bundles can be notified when a service they depend on is unregistered Class path dependencies are managed Model allows long running applications with dynamic software updates

86 ©1999-2004 aQute, All Rights Reserved slide #85 How To Use The Registry The Framework handles dependencies, but not all! Dont call us, we'll call you! Is Better. –Also know as the White Board approach Clients should register their objects, not the Servers. This is not intuitive! Significantly simplifies programming, therefore strongly advised

87 ©1999-2004 aQute, All Rights Reserved slide #86 White Board Approach See whitepaper: "Listeners Are Considered Harmful" Framework Client Server Client Server Add listener

88 ©1999-2004 aQute, All Rights Reserved slide #87 White Board Approach Registry Bundle A { } register WAP bundle Events: register, unregister Bundle C { } Bundle B { } Publisher get

89 ©1999-2004 aQute, All Rights Reserved slide #88 Threads Many tasks need to be done in a background thread –IO –Time related Threads cannot be stopped in Java –Some communication is used to request to stop them –A flag is reset –The thread is interrupted –Any IO channels are closed The continuous running model of OSGi requires that the threads remain alive, even when there are failures Failure handling must be careful not to overload the system

90 ©1999-2004 aQute, All Rights Reserved slide #89 Typical thread loop

91 ©1999-2004 aQute, All Rights Reserved slide #90 Assignment Write an application that sends out alive message on the network with UDP –Use your IP address as unique identifier Listen to the alive messages and register an Alive service for each station that has been discovered this way Unregister the service when no message has been received in 1 minute Make

92 ©1999-2004 aQute, All Rights Reserved slide #91 Native Code Native code allows a bundle to carry non-java code for different operation systems If a bundle has a Bundle-NativeCode manifest header, the bundle should contain native code libraries that must be available for the bundle to execute. When a bundle makes a request to load a native code library, the findLibrary method of the caller's classloader must be called to return the file path name in which the Framework has made the requested native library available. The bundle must have the required RuntimePermission[loadLibrary. ] in order to load native code in the OSGi Service Platform.

93 ©1999-2004 aQute, All Rights Reserved slide #92 Native Code The Bundle-NativeCode manifest header must conform to the following syntax: –Bundle-NativeCode ::= nativecode-clause (, nativecode- clause ) * –nativecode-clause ::= nativepaths ( ; env-parameter )* –Nativepaths::=jar-path ( ; jar-path )* –env-parameter::= (processordef | osnamedef | osversiondef | languagedef ) –Processordef::= processor = value –osnamedef::= osname = value –osversiondef::= osversion = value –Languagedef::= language = value –value ::= token | quoted-string

94 ©1999-2004 aQute, All Rights Reserved slide #93 Native Code The following is a typical example of a native code declaration in a bundles manifest: Bundle-NativeCode: /lib/http.DLL ; /lib/zlib.dll ; osname = Windows95 ; osname = Windows98 ; osname = WindowsNT ; processor = x86 ; language = en ; language = se, /lib/solaris/libhttp.so ; osname = Solaris ; osname = SunOS ; processor = sparc, /lib/linux/libhttp.so ; osname = Linux ; processor = mips

95 ©1999-2004 aQute, All Rights Reserved slide #94 Native Code If a Bundle-NativeCode clause contains duplicate env-parameter entries, the corresponding values must be ORed together. This feature must be carefully used because the result is not always obvious. This is highlighted by the following example: // The effect of this header // is probably not the intended effect! Bundle-NativeCode: /lib/http.DLL ; osname = Windows95 ; osversion = 3.1 ; osname = WindowsXP ; osversion = 5.1

96 ©1999-2004 aQute, All Rights Reserved slide #95 Native Code The previous example implies that the native library will load on Windows XP 3.1 and later, which was probably not intended. The single clause should be split up when the expected effect is desired: Bundle-NativeCode: /lib/http.DLL ; osname = Windows95 ; osversion = 3.1, /lib/http.DLL ; osname= WindowsXP ; osversion = 5.1 If multiple native code libraries need to be installed on one platform, they must be specified in the same clause for that platform.

97 ©1999-2004 aQute, All Rights Reserved slide #96 Native Code: Use Table OS NameVersionProcessorLanguageFilterLibs win32x86ennativecodewin32.dll, nativecode1win32.dll linuxx86en(org.osgi.framework.windowing.sy stems=gtk) nativecodegtk.so linuxx86en(org.osgi.framework.windowing.sy stem=qt) nativecodeqt.so

98 ©1999-2004 aQute, All Rights Reserved slide #97 Native Code Bundle-NativeCodenativecodewin32.dll; nativecode1win32.dll; processor=x86; osname=win32; language=en, nativecodegtk.so; processor=x86; osname=linux; selection-filter = (org.osgi.framework.windowing.system = gtk); language=en, nativecodeqt.so; processor=x86; osname=linux; selection-filter = (org.osgi.framework.windowing.system = qt); language=en If the native code algorithm fails to select a native code clause from the Bundle- NativeCode header, the bundle will fail to install and a BundleException will be thrown. The selection filter is used to select the appropriate clause based upon the windowing system.

99 ©1999-2004 aQute, All Rights Reserved slide #98 aQute www.aQute.biz +15123514821, Peter.Kriens@aQute.biz


Download ppt "aQute Bundle Programming By Peter Kriens CEO aQute OSGi Director of Technology & OSGi Fellow."

Similar presentations


Ads by Google