Introduction to OSGi

562
-1

Published on

An introduction to OSGi for Java developers. Describes the goals of OSGi and some best practices for using the module system.

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
562
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
13
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Introduction to OSGi

  1. 1. Daniel Selman – Product Architect, IBM WebSphere Decision Management6 November 2011Introduction to OSGi © 2009 IBM Corporation
  2. 2. IBM Presentation Template Full VersionModularity■ Since programming began we have tried to create modular and reusable components.■ No surprise since most programmers/engineers grew up with LEGO!API Function APIImage Wikipedia2 © 2011 IBM Corporation
  3. 3. Dealing with Change and Complexity ■ However our “bricks” are much more complex than LEGO and evolve over time ■ Input and outputs are defined using APIs ■ Some people call these APIs Services or Interfaces ■ We try to hide implementation details as much as possible – Lifecycle separation – Changing implementation vs. changing API Public API API Lifecycle Private! Implementation Lifecycle3 © 2011 IBM Corporation
  4. 4. What is a component? ■ Java has: – Field – Method – Class – Interface Who is the odd one out? – Package – JAR If the granularity is too small the programming model is inconvenient. If the granularity is too course then component transitive dependencies are problematic. E.g. Mavens “Download the Internet” syndrome.4 © 2011 IBM Corporation
  5. 5. What is a component? OSGi takes the view that a component is defined by a set of packages. The smallest component is therefore a single package.5 © 2011 IBM Corporation
  6. 6. OSGi Model Packages (API) My Component Packages (Implementation)6 © 2011 IBM Corporation
  7. 7. Component Dependencies ■ Real-world components will have dependencies on other components Change! A The role of a Module System is to minimize the scope of system changes C required when an individual component (API B A or implementation) changes.7 © 2011 IBM Corporation
  8. 8. API Changes ■ Without API versions any breaking API change cascades to all consumers... – Or effectively freezes components that are being consumed ■ In large (i.e. real-world) systems this is a show-stopper A Requires that Breaks! components have dependencies to C specific versions of an API. Breaks! OSGi uses semantic B A versioning.8 © 2011 IBM Corporation
  9. 9. Semantic Versioning ■ “version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.” http://semver.org/ ■ Take the form: x.y.z Wildcards or Version Ranges A v3.0.0 v2.5.* X = API breaking changes Requires API introduced in v2.5 Y = API compatible changes C Z = implementation changes v2.1.1 v1.*.* Uses B A v1.7.5 v1 API v1.6.2 Will only work With 1.6.2 (anti-pattern) D V1.0.09 © 2011 IBM Corporation
  10. 10. Implications ■ Implies a component developer will declare a version number for a component and adhere to the semantic versioning specification ■ Implies the runtime should support having component Foo version x,y,z and Foo version x,y,z deployed and running simultaneously ■ Implies that a component will declare its dependencies and optionally include version numbers, version ranges or wildcards ■ Implies that the runtime will bind a component to its “best” dependency based on the versions available ■ Implies No longer a flat JVM classpath...10 © 2011 IBM Corporation
  11. 11. Key OSGi Finding ■ Modularity without enforcement does not work ■ Developers eventually create dependencies on the internals of a component –Spagetti, Big Ball of Mud and a monolithic application results The OSGi runtime enforces modularity11 © 2011 IBM Corporation
  12. 12. Core OSGi Concepts and Terminology ■ Bundle: OSGi Component – A JAR with extra metadata in META-INF/MANIFEST.MF – A Bundle IS A JAR and can be added to the ClassPath and used outside OSGi ■ Package-Exports: the packages that compose a Bundles public API ■ Package-Imports: the packages that a Bundle requires ■ Class space: the classes visible within a Bundles classloader hierarchy ■ Require-Bundle: a mechanism to declare that a Bundle requires all the packages exported by another Bundle. ■ Fragment: an advanced mechanism that allows one Bundle to “patch” another Bundle – Try to avoid – “a fragment is like a virus, it requires a host”12 © 2011 IBM Corporation
  13. 13. Component Development Best Practices ■ Public API is defined by a set of packages – i.e. dont mix public API and implementation in the same package ■ Implementation is defined by a set of packages – By convention add the .internal suffix to the package name ■ The same package should not exist in multiple Bundles – Especially if they are exported – The so called “split package” problem. – You should try really hard not to get into this situation... ■ Give your Bundle a nice identifier. Usually this is the top-level package name of your public API. ■ OSGi metadata is created in MANIFEST.MF for the JAR you are building – Write the metadata by hand – Once confident, you can use BND to generate some metadata automatically – Apache Felix defines Maven support for BND13 © 2011 IBM Corporation
  14. 14. Sample MANIFEST.MF Meta-meta data Identifier ■ Manifest-Version: 1.0 Name 2 versions of this Bundle cannot coexist! ■ Bundle-ManifestVersion: 2 ■ Bundle-Name: %Plugin.Name ■ Bundle-SymbolicName: com.ibm.rules.studio.analytics;singleton:=true Semantic version ■ Bundle-Version: 7.6.0.0 ■ Bundle-Activator: com.ibm.rules.studio.analytics.PredictiveAnalyticsPlugin Called on load ■ Require-Bundle: ilog.rules.studio.ui;bundle-version="7.6.0" ■ Bundle-Vendor: %Plugin.Provider Imports a Bundle (anti-pattern) ■ Bundle-ClassPath: analytics.jar, ■ Bundle-ActivationPolicy: lazy Private Bundle classpath (anti-pattern) ■ Bundle-Localization: plugin ■ Export-Package: com.ibm.rules.analytics.bom Lazy is good... ■ Bundle-RequiredExecutionEnvironment: JavaSE-1.614 Execution environment Exported packages (API) Name of L10N file © 2011 IBM Corporation
  15. 15. Bundle-ClassPath ■ Allows you to package JARs inside your Bundle and have their contents added to your class space, and potentially exported ■ Useful and quite seductive. E.g. see the ilog.rules.shared Bundle ■ However often undermines goals of OSGi: – Leads to duplicate copies of JARs, each copy packaged within the Bundle – Metadata is lost – If the classes are exported from the Bundle, leads to a situation where your Bundle cannot coexist easily with Bundlized versions of those JARs – i.e. if a customer depends on ilog.rules.shared (because they want to use some of OUR code) they will also get OUR copies of non-IBM code imported into their class space. This is rude!15 © 2011 IBM Corporation
  16. 16. Require-Bundle ■ Introduced in OSGi for Eclipse – To deal with split packages – Extension points ■ Very common in Eclipse development ■ Used by lazy developers because they do not have to list the packages they import ■ Not recommended because: – Binds a component to a build artifact (a Bundle/JAR) rather than the explicit packages required – Too course-grained – Consumer no longer controls what is in their class space, the producer does – Can quickly get you into a situation where you dont know WHY a component has a dependency. The dependency can be on any exported package, including exports that were added after the consuming Bundle was created.16 © 2011 IBM Corporation
  17. 17. Package Dependencies ■ OSGi contains no silver bullets! ■ Still need to design API and think about package dependencies ■ In this dependency diagram a row may depend on a row beneath it ■ Note the arrows that show problematic dependencies... ■ Try to think in terms of diagrams like this Generated using Structure 101 Headway Software17 © 2011 IBM Corporation
  18. 18. Getting an Instance ■ My public API consists of interfaces and only the interfaces are exported from my Bundle – Good! ■ How does a consumer create an instance of my interface? ■ Three options: – Export a Factory – Use Dependency Injection – Use a Broker A component doesnt know which implementation of an interface he is using?18 © 2011 IBM Corporation
  19. 19. Export a Factory ■ Add a factory to your public API with a create method for your type ■ Unfortunately the create method must reference a type in your internal implementation package... ■ Tightly couples the public API package and the internal implementation package – E.g. changing the constructor of your internal class have a ripple effect on your factory, forcing your to re-version both19 © 2011 IBM Corporation
  20. 20. Use Dependency Injection ■ Use a DI framework to inject your implementation into your factory or a consumer directly ■ All you have done is move the instantiation logic into some sort of XML file where it is even harder to maintain ■ Changes to the constructor signature still require changes outside of your module20 © 2011 IBM Corporation
  21. 21. Use a Broker ■ When your Bundle is started classes are instantiated and registered in a global registry ■ When a consumer wants to access an implementation they consult the registry: “give me an implementation of interface X” ■ The consumers and producers are decoupled ■ Consumers must deal with some new failure cases: – There is no interface available – Interfaces may go away at runtime ■ Three mechanisms to declare services and have them registered in the OSGi Service Registry and control their lifecycles: – OSGi Declarative Services – OSGi Blueprint (basically Spring inside OSGi) – Apache Felix iPOJO ■ I am most familiar with OSGi Blueprint...21 © 2011 IBM Corporation
  22. 22. Service Dynamicity ■ OSGi was designed with dynamicity in mind – i.e. Bundles can be deployed/undeployed without restarting the OSGi runtime ■ However many systems (including Rule Studio...) assume that Bundles will not be undeployed after start-up ■ Coding for dynamic services is harder than ignoring the issue – Requires your code to do something sensible when services are missing or if multiple services are available ■ It is up to you to determine whether the ability to deploy, redeploy services at runtime merits the design and implementation overhead.22 © 2011 IBM Corporation
  23. 23. Some Anti-Modularity Patterns ■ Put the name of a class in a file, assume you can Class.forName the class name – Sadly this is quite common in a variety of open source Java libraries ■ Load-time byte code modification – Often relies on specific class loaders or JVM agents – This sort of code (e.g. JPA) requires specific treatment within an OSGi runtime ■ Java serialization – The .ser file contains class names. Cannot always guarantee that the classes are in the class space of the Bundle that will deserialize23 © 2011 IBM Corporation
  24. 24. Questions? Go forth and be modular!24 © 2011 IBM Corporation
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×