introduction to osgi (tokyo jug)
DESCRIPTION
TRANSCRIPT
Introduction to OSGiNeil Bartlett – 東京 2009年12月23日
Brief Intro to OSGi
❶
OSGi: The Module System for Java
Standard Java
ABC.JAR
JARs are Deployment
Units
They are Not Modules
Meaningful name
Version
Vendor
Exports
Dependencies
What’s Missing?
ABC.JAR
Dependencies
JARs do have dependencies
They are implicit.
A dependency is an assumption.
“I assume module X (version Y) is on the
classpath. If not I will crash and burn.”
Module = “Bundle”
Meaningful name
Version
Vendor
Exports
Dependencies
Just a JAR + Metadata
org.foo.mylibManifest-Version: 1.0Bundle-SymbolicName: com.mylibBundle-Name: My Library BundleBundle-Vendor: Neil BartlettBundle-Version: 1.0.0Import-Package: javax.swing, org.w3c.domExport-Package: com.mylib1.ui;version=“1.0.0”, com.mylib1.util;version=“1.0.0”Bundle-RequiredExecutionEnvironment: J2SE-1.5
MANIFEST.MF
Manifest-Version: 1.0Bundle-SymbolicName: com.mylibBundle-Name: My Library BundleBundle-Vendor: Neil BartlettBundle-Version: 1.0.0Import-Package: javax.swing, org.w3c.domExport-Package: com.mylib.ui;version=“1.0.0”, com.mylib.util;version=“1.0.0”Bundle-RequiredExecutionEnvironment: J2SE-1.5
Works Outside OSGi
Dependency Graphs
com.foo.bar
javax.swing
org.wibble
Imports..... and Exports
com.mylib
com.mylib.ui
com.mylib.util} {
Package Resolution
com.foo.bar
A
Package Resolution
com.foo.bar
A
com.foo.bar
B
Package Resolution
com.foo.bar
A
com.foo.bar
B
Versioned Dependency
com.foo.bar
[1.2.0,1.4.0) A
Versioned Dependency
com.foo.bar
[1.2.0,1.4.0) A
com.foo.bar
1.4.5B
Versioned Dependency
com.foo.bar
[1.2.0,1.4.0) A
com.foo.bar
1.4.5B ✘
Versioned Dependency
com.foo.bar
[1.2.0,1.4.0) A
com.foo.bar
1.3.12B’
Versioned Dependency
com.foo.bar
[1.2.0,1.4.0) A
com.foo.bar
1.3.12B’
Side-by-Side Versions
com.foo.bar
1.4.5
com.foo.bar
1.3.12
com.foo.bar
[1.2.0,1.4.0)
com.foo.bar
[1.4.0,1.5.0)B
B’
X
Y
Side-by-Side Versions
com.foo.bar
1.4.5
com.foo.bar
1.3.12
com.foo.bar
[1.2.0,1.4.0)
com.foo.bar
[1.4.0,1.5.0)B
B’
X
Y
How it Works
Bundle-SymbolicName: com.mylib1Bundle-Version: 1.2.0Export-Package: com.mylib1.ui;version=“1.2.0”, com.mylib1.util;version=“1.2.0”
Bundle-SymbolicName: com.app1Bundle-Version: 2.2.3.alphaImport-Package: com.mylib1.ui;version=“[1.2.0,1.3.0)” com.mylib1.util;version=“[1.2.0,1.3.0)”
Private Internals
Exports must be stated explicitly
Packages not listed in “Export-Package” are not
available to other bundles
Versions
Standard numbering scheme with well-defined
ordering.
major.minor.micro.qualifier
First three numeric, last alphanumeric
Eg 1.0.0.beta2
Unspecified ! 0.0.0
Version Ranges
Open, closed or implicit
[1.0.0, 2.0.0] ! 1.0.0 ! version ! 2.0.0
[1.0.0, 2.0.0) ! 1.0.0 ! version < 2.0.0
Informally “1.*”
1 ! [1.0.0, ")
Unspecified ! [0.0.0, ")
Our Promise*: No More
NoClassDefFoundErrors!
Dynamic!Dynamic!
Dynamic
Install Bundles
Update Bundles
Uninstall Bundles
... all “on the fly”
OSGi in Infrastructure
❷
OSGi is the King of Infrastructure
All Major JEE Application Servers use OSGi
Most ESBs use OSGi
2 of 3 Open Source IDEs use OSGi
Even Build Tools (Maven and Hudson) Moving to OSGi
Where are the “Business” Apps?
OSGi for Applications
Until Recently, Application Servers used OSGi “on the inside”
Now SpringSource dm Server, Paremus Infiniflow, WAS 7, GlassFish v3 and WebLogic DM all expose OSGi
Application Developers can Finally Deploy OSGi bundles to their OSGi servers!
Why is OSGi Attractive for Application Development?
The Failure of Object Oriented Programming
❸
OOP Was Meant to Enable Reuse
HARDER THAN EXPECTED!
“Building a new system would be a snap. Just get a
few classes, bunch them together... and voila!”
– Peter Kriens
What Went Wrong??
Tight Coupling
COMPLEXITY
Classes coupled to Other Classes
Packages coupled to Other Packages
Packages coupled to JARs
JARs coupled to More JARs
Which are coupled to yet more JARs...
Dependency Injection?
DI Frameworks
Provide “Late Binding” of Implementations to Interfaces
But Not Late Enough!
Spring Framework
<bean id="MyBean" class="org.example.MyBean"> <property name="dataSource" ref="OracleDataSource"/></bean>
<bean id="OracleDataSource" class="..."> <property name="..." /></bean>
Traditional Spring
Static DI
“Beans” are wired together once, at start-up
They cannot be rewired
Limited support for optional dependencies
FRAGILE
One Solution: Give Up!
Reuse is Hard, So Don’t Try!
Leave Code in One Place, and Call Remotely
(...also known as “SOA”)
Component Oriented Programming
❹
What is a “Component”?
The Usual Analogy:
LEGO?
Not Really...
Dead Lumps of Plastic
Many Copies of the Same Thing
BIOLOGY
BIOLOGY
Dr Alan Kay
Inventor of Object Oriented Programming & Smalltalk
“I thought of objects being like biological cells...”
Components
Do Something, or Provide Something
Aware of and Adapt to their Environment
Have a Life-cycle (birth to death).
“Do” Something
Open a socket
Monitor a device
Poll a queue
Display a GUI
.... etc.
“Provide” Something
Publish a Service – may be used by other components
The “Environment”
The “Environment” of a Component means:
Services provided by other Components
Resources, Devices, Network etc
Components Adapt to their Environment
Most services are available
The component flourishes
Good Environment
Harsh Environment
Some non-essential services are unavailable
Component adapts and survives
Very Harsh Environment
Essential services are unavailable
Component hibernates or dies
Composition
Components Use other Components
In this way, whole Systems are Composed
Resilient, Elastic Systems
Developing Components
❺
Services
Components provide Services
Registered with a Service Registry
Services are POJOs!
Looked up by Java interface name
In-Process SOA
ServiceProviderService
Consumer
ServiceBroker
Client Service
RegisterFind
Bind
ServiceContract
Plain Old Java Objects
The Glue Between Components
Dynamics Make Services Slippery
We Don’t Code Directly against Services (it’s too hard!)
Let a Framework Handle the Hard Stuff
Choice of Frameworks
Declarative Services (DS)
Blueprint (from Spring-DM)
iPOJO
Guice Peaberry
Framework Interop
Perfect Interoperability of these Frameworks!
No need to choose “The One True Framework”
Use 3rd-party components implemented with other frameworks.
Examining DS
Dynamic dependency injection (DI)
... and “uninjection”
Starting Point...
import javax.sql.DataSource;
public class DbMailbox implements Mailbox {
private DataSource dataSource; void setDataSource(DataSource ds) { /*...*/ } void unsetDataSource(DataSource ds) { /*...*/ }
public long[] getAllMessages() { // ... }}
Starting Point...
import javax.sql.DataSource;
public class DbMailbox implements Mailbox {
private DataSource dataSource; void setDataSource(DataSource ds) { /*...*/ } void unsetDataSource(DataSource ds) { /*...*/ }
public long[] getAllMessages() { // ... }}
No OSGi API Used
Starting Point...
import javax.sql.DataSource;
public class DbMailbox implements Mailbox {
private DataSource dataSource; void setDataSource(DataSource ds) { /*...*/ } void unsetDataSource(DataSource ds) { /*...*/ }
public long[] getAllMessages() { // ... }}
No OSGi API Used
JavaBeans Style => Testable
Make it a Componentimport javax.sql.DataSource;
@Componentpublic class DbMailbox implements Mailbox {
private DataSource dataSource; @Reference(service = DataSource.class) void setDataSource(DataSource ds) { /*...*/ } void unsetDataSource(DataSource ds) { /*...*/ }
public long[] getAllMessages() { // ... }}
Annotations
@Component – Create a Component of this type.
Service is automatically published
@Reference – Use the specified service
Add Life-cycle
@Activate void start() { thread = new Thread(); thread.start(); } @Deactivate void stop() { thread.interrupt(); }
Make it Configurable @Activate void start(Map<String, Object> configuration) { thread = new Thread(); thread.start(); } @Modified void modify(Map<String, Object> newConfiguration) { // This method is optional } @Deactivate void stop() { thread.interrupt(); }
Optional Reference
@Reference(service = LogService.class, optional = true)void setLogService(LogService log) { /* ... */ }void unsetLogService(LogService log) { /* ... */ }
Multiple Reference
@Reference(service = MailboxListener.class, multiple = true)void addListener(MailboxListener listener) { /* ... */ }void removeListener(MailboxListener listener) { /* ... */ }
DEMO
❻
Mailbox Reader
Fixed
Mailbox
Mailbox
Mailbox Reader
GrowingMailbox
MailboxListener
Mailbox
Mailbox Reader
TradesMailbox
MailboxListener
Mailbox
EventHandler
Event Broker
EventAdmin
Trade MatchingEngine
Order Entry
MatchingService