JavaOne 2010: OSGI Migrat

39
S314613: OSGI Migration headaches Krasimir Semerdzhiev SAP Labs Bulgaria Development Architect Peter Peshev SAP Labs Bulgaria Development Architect

description

The session details are accessible over here: http://www.eventreg.com/cc250/sessionDetail.jsp?SID=314613 Session abstract Nowadays, every platform considers having the "OSGi supported" checkbox ticked and offers "easy" and "smooth" migration from the classical Java EE world to the new "modular" future. In spite of the multiple guidelines and best practices, migrating from a monolithic Java EE application to OSGi remains a pain and reveals a number of hidden and time-consuming pitfalls and hurdles. The session will guide you through the usual problems that every project faces on its way to holy modularity, providing helpful tips and tricks on how to quickly find your way through the maze of NoClassDeffFound, ClassCast, and other OSGi-specific errors.

Transcript of JavaOne 2010: OSGI Migrat

Page 1: JavaOne 2010: OSGI Migrat

S314613:

OSGI Migration

headaches

Krasimir SemerdzhievSAP Labs BulgariaDevelopment Architect

Peter PeshevSAP Labs BulgariaDevelopment Architect

Page 2: JavaOne 2010: OSGI Migrat

OSGI intro

Headaches

Painkiller options

Q&A

Agenda

Page 3: JavaOne 2010: OSGI Migrat

Modularity

Page 4: JavaOne 2010: OSGI Migrat

Alternative implementations

VW Golf

91-97

Page 5: JavaOne 2010: OSGI Migrat

Java VM

log4j barcode4j axis batik commons

derbyfopezmorphfreemarkerhttpunit

jakarta jcl json jdbm jdom

jenks jpos18 jython looks lucene

mail mx4j naming jetty poi

resolver rome serializer servlets tomcat

velocity

ws-commons

xalan

wsdl4j

xerces

xmlgraphics

xmlrpc

xmlapis

..

geronimo

bsh

bsf

guiapp hhfacility manufact. marketing minerva

accounting assetmaint

base

bi

catalinacommon

oagis order

ebaycontent

datafile

ecommerce

entity

googlebase

Application layer

widget

minilang party pos. product workeffort workflow …

sunjce_prov.pluginjssejcert dnsns ..

Libs

Good architecture and interchangeable

Page 6: JavaOne 2010: OSGI Migrat

Java VM

log4j

barcode4j

axis

batik

commons

derby

fop

ezmorph

freemarker

httpunit

jakarta

jcl

json

jdbm

jdom

jenks

jpos18

jython

looks

lucene

mail

mx4j

naming

jetty

poi

resolver

rome

serializer

servlets

tomcat

velocity

ws-commons

xalan

wsdl4j

xerces

xmlgraphics

xmlrpc

xmlapis

..

geronimo

bsh

bsf

guiapp

hhfacility

manufact.

marketing

minerva

accounting

assetmaint

base

bi

catalina

common

oagis

order

ebay

content

datafile

ecommerce

entity

googlebase

ofbiz

widget

minilang

party

pos.

product

workeffort

workflow

sunjce_prov

.

plugin

jsse

jce

rt

dnsns

..

Class

Not

Found

Exception

Begin

Here

Problem: CLASSPATH

Page 7: JavaOne 2010: OSGI Migrat

The OSGi Alliance

Started March 1999 as an initiative from ERICSSON, SUN and IBM

Today: A stable Alliance with almost 100 members

Now practically all of the Java Server vendors are represented there

A standardization body…

Page 8: JavaOne 2010: OSGI Migrat

OSGi Framework Layers

Staircase

Applications can make use

of different layers directly

Module Layer defines

packaging , deployment

dependancies among

modules

Lifecycle Layer controls

lifecycyle operations of a

bundle

Page 9: JavaOne 2010: OSGI Migrat

Module Layer: Bundles

Bundles

Are JAR files

Contain classes, other resources like HTML, images, specific metadata

Contain manifest file (META-INF/MANIFEST.MF) with OSGI specific

headers used to manage the bundle

Describes the content of the JAR file

Export \ Import package

Require-Bundle

Page 10: JavaOne 2010: OSGI Migrat

Module Layer: Runtime class loading

load class com.foo.classA

Page 11: JavaOne 2010: OSGI Migrat

Class Loading Architecture: Class Space

Page 12: JavaOne 2010: OSGI Migrat

Class Loading Architecture: Delegation

Basic properties

Parent delegation

Wire importers and exporters

There can be fragment bundles

Class loading traversal based on importers and their wires

Page 13: JavaOne 2010: OSGI Migrat

Lifecycle Layer

Runtime representation of bundles

For every bundle, the framework creates a Bundle java object

Bundles are identified by Bundle ID, Bundle Symbolic Name and

Bundle Location

Bundle has a runtime state:

Page 14: JavaOne 2010: OSGI Migrat

What is the story?

Java EE compliant runtime

EAR file

EAR file

Web Modules

Web Modules

Web Module

(war)

Lib Lib Lib Lib

OSGi framework

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

bundle

State 2

OSGi framework

Web

Modules

Web Modules

Web Module

(war)

bundle

bundle

bundle

bundle

Page 15: JavaOne 2010: OSGI Migrat

What do we aim to get from OSGi?

■ Standardized execution environment

■ Java-based modularization

■ Well defined module contract

■ Strict dependency management at build and run time

■ Manifest as a single point of truth

■ Deterministic declarative runtime resolution

or in other words…

■ Evolve from JARs/modules to “interchangeable/reusable parts”

Page 16: JavaOne 2010: OSGI Migrat

OSGI intro

Headaches

Painkiller options

Q&A

Agenda

Page 18: JavaOne 2010: OSGI Migrat

Step 2: How to create bundles?

Manifest-Version: 1.0

Bundle-Name: My First Bundle

Bundle-SymbolicName: com.acme.myfirstbundle

Bundle-Version: 1.0.0

Bundle-Description: Small Bundle

Bundle-Vendor: ACME

Bundle-Activator: com.acme.myfirstbundle.impl.Activator

Bundle-Category: example

Import-Package: org.osgi.framework

Export-Package: com.acme.myfirstbundle.api

Export-Package ::= export(‘,’ export)*

export ::= package-names(‘;’ parameter)*

package-names ::= package-name(‘;’ package-name)*

Import-Package ::= import(‘,’ import)*

import ::= package-names(‘;’ parameter)*

package-names ::= package-name(‘;’ package-name)*

Require-Bundle ::= bundle-description ( ',' bundle-description )*

bundle-description ::= symbolic-name (';' parameter )*

Page 19: JavaOne 2010: OSGI Migrat

Step 2: How to create bundles?

authentication

catalog

catalog.types

database

diag

iapi

iapi.db

iapi.error

iapi.jdbc

iapi.security

iapi.services

iapi.services.cache

iapi.services.classfile

iapi.services.compiler

iapi.services.context

iapi.services.crypto

iapi.services.daemon

iapi.services.diag

iapi.services.i18n

iapi.services.info

iapi.services.io

iapi.services.jmx

iapi.services.loader

iapi.services.locks

iapi.services.memory

iapi.services.monitor

iapi.services.property

iapi.services.stream

iapi.services.timer

iapi.services.uuid

iapi.sql

iapi.sql.compile

iapi.sql.conn

iapi.sql.depend

iapi.sql.dictionary

iapi.sql.execute

iapi.store

iapi.store.access

iapi.store.access.conglomerate

iapi.store.access.xa

iapi.store.raw

iapi.store.raw.data

iapi.store.raw.log

iapi.store.raw.xact

iapi.store.replication

iapi.store.replication.master

iapi.store.replication.slave

iapi.tools

iapi.tools.i18n

iapi.types

iapi.util

impl

impl.db

impl.io

impl.io.vfmem

impl.jdbc

impl.jdbc.authentication

impl.load

impl.services

impl.services.bytecode

impl.services.cache

impl.services.daemon

impl.services.jce

impl.services.jmx

impl.services.jmxnone

impl.services.locks

impl.services.monitor

impl.services.reflect

impl.services.stream

impl.services.timer

impl.services.uuid

impl.sql

impl.sql.catalog

impl.sql.compile

impl.sql.conn

impl.sql.depend

impl.sql.execute

impl.sql.execute.rts

impl.store

impl.store.access

impl.store.access.btree

impl.store.access.btree.index

impl.store.access.conglomerate

impl.store.access.heap

impl.store.access.sort

impl.store.raw

impl.store.raw.data

impl.store.raw.log

impl.store.raw.xact

impl.store.replication

impl.store.replication.buffer

impl.store.replication.master

impl.store.replication.net

impl.store.replication.slave

impl.tools

impl.tools.sysinfo

info

io

jdbc

loc

mbeans

osgi

security

shared

shared.common

shared.common.error

shared.common.sanity

tools

vti

Let‘s take one example – Apache Derby

org.apache.derby.*

Page 20: JavaOne 2010: OSGI Migrat

Step 2: How to create bundles?

authentication

catalog

catalog.types

database

diag

iapi

iapi.db

iapi.error

iapi.jdbc

iapi.security

iapi.services

iapi.services.cache

iapi.services.classfile

iapi.services.compiler

iapi.services.context

iapi.services.crypto

iapi.services.daemon

iapi.services.diag

iapi.services.i18n

iapi.services.info

iapi.services.io

iapi.services.jmx

iapi.services.loader

iapi.services.locks

iapi.services.memory

iapi.services.monitor

iapi.services.property

iapi.services.stream

iapi.services.timer

iapi.services.uuid

iapi.sql

iapi.sql.compile

iapi.sql.conn

iapi.sql.depend

iapi.sql.dictionary

iapi.sql.execute

iapi.store

iapi.store.access

iapi.store.access.conglomerate

iapi.store.access.xa

iapi.store.raw

iapi.store.raw.data

iapi.store.raw.log

iapi.store.raw.xact

iapi.store.replication

iapi.store.replication.master

iapi.store.replication.slave

iapi.tools

iapi.tools.i18n

iapi.types

iapi.util

info

io

jdbc

loc

mbeans

osgi

security

shared

shared.common

shared.common.error

shared.common.sanity

tools

vti

Apache Derby – impl.* gone

org.apache.derby.*

Page 21: JavaOne 2010: OSGI Migrat

Step 2: How to create bundles?

authentication

database

io

jdbc

vti

org.apache.derby.*

Apache Derby – what Eclipse uses out of it :-)

or in other words…

■ Don’t rush to define manifests, for modules you know nothing of!

How to create manifests?

By hand

BND tool

Apache Felix Maven plugin

Eclipse PDE

Bundlor

Page 22: JavaOne 2010: OSGI Migrat

Step 3: Let‘s try to activate the bundle.

java.lang.NoClassDefFoundException

Possible causes?

Missing import-package

Missing export-package

Import version mismatch [1.2.3, 2.0); “1.2.3”

Forgotten/missing component (really missing!)

Wrong boot class delegation property

Missing file system permissions (can’t read the JARs)

The forName() method in class Class.

The findSystemClass method() in class ClassLoader.

The loadClass() method in class ClassLoader

Class definition is

missing!

Page 23: JavaOne 2010: OSGI Migrat

java.lang.NoClassDefFoundError

Possible causes?

Exception in static block

Missing imported class (NoClassDefFoundException for it)

Class version mismatch

Hotspot reflection JIT optimizations (BugID 6265952 )

(injection of sun.misc.Unsafe.defineClass)

Step 3: Separate a the first library as a bundle

Class definition is

found, but

instantiation failed!

or in other words…

■Don’t rush blaming the framework! Classloading there is quite solid!

Page 24: JavaOne 2010: OSGI Migrat

Step 4: Iterative refactoring

My bundle is not updated?!

Possible causes?

Did you update the version?

You’re replacing your bundle directly in the equinox plugins folder

Package-imports do not fit to the new bundle version?

or in other words…

■Don’t rush blaming the framework! ;)

Page 25: JavaOne 2010: OSGI Migrat

java.lang.ClassCastError

Possible causes?

Additional copies (besides the system bundle) of the

OSGi framework classes

Undesired additional JARs in classpath

■Clash between RT.jar and application libs(previously used embedded jars)

■Java SE 5 vs. Java SE 6 does make a difference… (a bunch of new packages added (StAX, JDBC 4.0, JAXB 2.0, etc.)

Step 4: Iterative refactoring

or in other words…

■Make sure you understand the root cause. (try using Eclipse Memory Analyzer)

Page 26: JavaOne 2010: OSGI Migrat

Step 4: Iterative refactoring

Works in Eclipse, but doesn‘t work in Equinox

Possible issues

■Different setting of org.osgi.parentClassloader

■ app (default for Eclipse)

■ boot

■ ext

■ fwk

Certain expectations of org.osgi.framework.system.packages

Different values of org.osgi.framework.bootdelegation

■property osgi.compatibility.bootdelegation (default for Eclipse is false)

or in other words…

■Don’t be fooled by configuration differences

Page 27: JavaOne 2010: OSGI Migrat

Step 4: Design flaws

Dependencies on startup order

Possible causes?

■Avoid lookup-error-fail patterns

■As a last resort – you can use start levels

■Keep Activators really lean.

■Typically seen when extracting code from a web module with fixed

Servlet.init() order.

or in other words…

■Don’t do anything needless in your activator. That’s not init()/start()!

Page 28: JavaOne 2010: OSGI Migrat

Step 4: Design flaws

Classloader resource assumptions

Possible issues

■JAR files

■Folder containing class files/packages

■URLs (to any of the above)

■new File(<resource>), after loader resources iteration“bundle:xxx” as a resource

or in other words…

■Don’t make assumptions on the classloader resources!

Page 29: JavaOne 2010: OSGI Migrat

Step 4: Design flaws

Boot delegation specifics

■org.osgi.framework.bootdelegation – shortcut the OSGi resolution

■Adding com.foo.* includes all sub-packages, but not the com.foo

package itself.

■osgi.compatibility.bootdelegation - true/false

or in other words…

■Make sure that you understand the setup of your OSGi environment

Page 30: JavaOne 2010: OSGI Migrat

Step 5: Design flaws

SPI pattern limitations

Possible issues

■Load a class, described in some meta-data file, used via interface

■ META-INF/services/javax.xml.ws.spi.Provider

■Explicit import of the impl packages is required!

Page 31: JavaOne 2010: OSGI Migrat

Step 5: Design flaws

My process exits unexpectedly?!

Possible issues

■Lots of code is written with the assumption that it owns the world and not

that it lives in a small corner of it.

■Enabling a Security Manager which traces System.exit() and Runtime.halt()

calls might help

Page 32: JavaOne 2010: OSGI Migrat

Step 5: Design flaws

Registering objects in the VM has direct impact on the

ability to stop a bundle

Possible issues

■System in and out streams

■Shutdown hooks

■MBean server factory

■Log4J formatters

■JNDI provider/factory

or in other words…

■Don’t try to do the job of the underlying middleware.

Some of those

have nounregister methods!

Page 33: JavaOne 2010: OSGI Migrat

Step 5: Design flaws

ContextClassLoader usage

Possible issues

■Some code written to run in a web app might make some assumptions on

the Context classloader.

■One example here is JNDI.

or in other words…

■Consider environment dependencies when extracting code into bundles

Page 34: JavaOne 2010: OSGI Migrat

OSGI intro

Headaches

Painkiller options

Q&A

Agenda

Page 35: JavaOne 2010: OSGI Migrat

Eclipse Virgo shell improvements

Supportability commands

■ Nested OSGi frameworks

■ Classloading

Page 36: JavaOne 2010: OSGI Migrat

SpringSource Tool Suite

Page 37: JavaOne 2010: OSGI Migrat

Other relevant sessions

Tue 12:00 PM Developing OSGi-Enabled Java EE Applications

Tue 6:00 PM Patterns for modularity

Tue 6:00 PM OSGI BOF

Tue 9:00 PM OSGi at a Large-Scale Enterprise: Lessons from eBay

Wed 10:00 AM Java EE OSGi applications : Design and Deployment for On-Premises and Cloud

Wed 1:00 PM OSGi and JSR 294: Module Keyword

Wed 4:45 PM Visualizing the Science of Conversation with JavaFX and OSGi to Save Lives

Thu 3:30 PM Creating Modular Applications with Apache Aries and OSGi

Thu 3:30 PM Developing Rich Modular Clients with Java, JavaFX and OSGi Technology

Page 38: JavaOne 2010: OSGI Migrat

Q&A?