More Related Content
Similar to Introduction to OSGi (20)
Introduction to OSGi
- 1. Daniel Selman – Product Architect, IBM WebSphere Decision Management
6 November 2011
Introduction to OSGi
© 2009 IBM Corporation
- 2. IBM Presentation Template Full Version
Modularity
■ Since programming began we have tried to create modular and reusable components.
■ No surprise since most programmers/engineers grew up with LEGO!
API
Function
API
Image Wikipedia
2 © 2011 IBM Corporation
- 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
Lifecycle
3 © 2011 IBM Corporation
- 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. Maven's “Download the
Internet” syndrome.
4 © 2011 IBM Corporation
- 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. OSGi Model
Packages
(API)
My Component
Packages
(Implementation)
6 © 2011 IBM Corporation
- 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. 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. 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.0
9 © 2011 IBM Corporation
- 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. 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 modularity
11 © 2011 IBM Corporation
- 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 Bundle's public API
■ Package-Imports: the packages that a Bundle requires
■ Class space: the classes visible within a Bundle's 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. Component Development Best Practices
■ Public API is defined by a set of packages
– i.e. don't 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 BND
13 © 2011 IBM Corporation
- 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.6
14 Execution environment Exported packages (API) Name of L10N file © 2011 IBM Corporation
- 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. 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 don't 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. 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 Software
17 © 2011 IBM Corporation
- 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 doesn't know which
implementation of an interface he is using?
18 © 2011 IBM Corporation
- 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 both
19 © 2011 IBM Corporation
- 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 module
20 © 2011 IBM Corporation
- 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. 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. 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 deserialize
23 © 2011 IBM Corporation
- 24. Questions?
Go forth and
be modular!
24 © 2011 IBM Corporation