Introduction to OSGi (Tokyo JUG)

Post on 16-Nov-2014

3,484 views 2 download

Tags:

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