OSGi Integration

Layers for Tuscany/SCA OSGi integration

Assembling Tuscany runtime from OSGi bundles for tuscany modules and 3rd party jars

OSGi providing modularity of the Tuscany runtime itself (business as usual for OSGi and not a programming model relationship). Package tuscany runtime modules and 3rd party dependencies as OSGi bundles, and use an OSGi runtime such as Felix or Equinox to install/run these bundles. This feature enables the assembly of Tuscany runtime as OSGi bundles and it formalizes the SPI contracts (class visibility across modules) using the OSGi Import-Package/Export-Package headers.

Objectives:

  • Formalize the SPI contracts and enforce the class dependencies across modules
  • Provide versioning and isolation support that so different tuscany extensions can depend on different versions of the same library
  • Provide dynamic lifecycle for extensions, install/uninstall/start/stop a module

Key Modules:

These two modules enable the META-INF/services provider pattern to work with the OSGi bundles.

This special launcher will discover tuscany bundles and 3rd party jars on paths defined by TUSCANY_HOME and TUSCANY_PATH system properties/environment variables. It will start an embedded OSGi runtime (Felix, Equinox or other), install (or wrap plain jars into) bundles, and use the SCA Node/Domain APIs to create/launch SCA nodes or domain manager.

The following testcase demonstrates the usage of this launcher to run HelloWorld composite and SCA Domain Manager:
/tuscany-node2-launcher-osgi/src/test/java/org/apache/tuscany/sca/node/osgi/launcher/NodeLauncherTestCase.java

Using OSGi bundles as SCA contributions

Package application artifacts into OSGi bundles and contribute them to SCA domain as SCA contributions

OSGi bundles as SCA contributions (OSGi providing modularity for Java implementation types (e.g. implementation.osgi and implementation.java)).

Implementing SCA components using OSGi bundles

Support OSGi bundle as a component implementation type for Tuscany/SCA, expose OSGi services as SCA services and inject references to OSGi services

OSGi bundles as an implementation technology for SCA components (implementation.osgi). Here OSGi services and references are mapped to SCA services/references and can be integrated with other
implementation technologies (e.g. BPEL, POJO, Groovy, etc...) and invoked or can invoke over the various SCA bindings. This is business as usual for SCA, which is designed to enable the assembly of
heterogeneous implementation technologies.

Running environment

  • JSE with embedded OSGi runtime such as Eclipse Equinox and Apache Felix
  • Running inside Eclipse workspace
  • Maven surefire plugin for testing
  • External OSGi runtime such as Eclipse or Felix Shell
  • Other environment such as JEE (Web Container, EJB container)

Different approaches to convert 3rd party jars into OSGi

Strategy

Options

Pros

Cons

Note

Build-time conversion

Using tools (such as maven-bundle-plugin) to convert plain jars into OSGi bundles

  • Ready-to-use bundles for any OSGi runtime
  • No addtional runtime overhead to convert the jars
  • More control on how packages are imported/exported
  • Extra steps are required to build the bundles first and it increases the complexibilty for development testing inside an IDE such as Eclipse
  • Two sets of jars are created
  • Maven build uses different jars than the OSGi bunldes which are not published into maven

Maven Bundle Plugin:

http://felix.apache.org/site/maven-bundle-plugin-bnd.html\\\\\\\\\\\\\\\\\\\\\\\\

Felix Commons: http://felix.apache.org/site/apache-felix-commons.html
Ecipse Orbit: http://www.eclipse.org/orbit/
Spring DM Repo: http://static.springframework.org/osgi/docs/1.1.1/reference/html/appendix-osgi-repo.html

 

Use already-converted 3rd party bundles from Spring DM, Felix Common or Eclipse Orbit

 

Not all 3rd party jars are available in OSGi bundles

 

Runtime converstion

Before the jar is installed (BundleContext.installBundle())

 

  • Tuscany needs to install the bundles
  • Performance impact

 

 

Add a hook to the OSGi runtime to wrap the jar (such as

 

 

Equinox Hooks:
http://wiki.eclipse.org/index.php/Adaptor_Hooks http://www.eclipsecon.org/2008/sub/attachments/Equinox_Framework_How_to_get_Hooked.pdf

Hybrid conversion

Build-time will generate the META-INF/MANIFEST.MF as a side file
Runtime will wrap the 3rd party jar with the side file

 

 

 

Virtual Libary Bundle for 3rd party jars

1) The launcher looks for runtime JARs and class folders in a Tuscany distribution install or just the classpath entries used to start it.

2) Then it looks for OSGi Bundle-SymbolicName entries in their manifests to determine if they are OSGi bundles or just regular JARs.

3) It creates a single in-memory bundle for these regular JARs, in an Equinox BundleFileFactoryHook:

  • export and import all their packages
  • import * with a DynamicImport
  • reference the JARs outside of the bundle in Bundle-classpath

That step is fast as it just writes a Manifest to a byte[] in memory, with no need to copy the JARs and re-package them, as the manifest
simply references their actual locations.

4) Bundle tuscany-extensibility-equinox contains a DynamicImport *, enabling ServiceDiscovery to access the 3rd party packages.

5) Instead of Thread.getContextClassLoader(), Tuscany code must use Class.forName() from modules that have the proper imports, and the
Tuscany ServiceDiscovery to discover META-INF/services.

The above seems to work well in the following environments:

  • an installed distro, JARs and bundles are loaded from the distro
  • Maven surefire, classes are loaded from the Maven repos
  • an Eclipse project, classes are loaded from the project's classpath

Build a distribution with the OSGi bundle layout

tuscany-sca
...modules
......tuscany-module.jar
...lib
......3rd-party-non-osgi
.........META-INF/MANIFEST.MF
.........3rd-party-non-osgi.jar
......3rd-party-osgi.jar

Tuscany OSGi Integration

Enable Tuscany runtime with OSGi (Use OSGi under the cover for Tuscany runtime or work with existing OSGi environment such as Eclipse RCP)

Work Items

Status

Package Tuscany modules as OSGi bundles

Partially done. The following items remain:

  • Share the maven bundle plugin configuration
  • Rationalize the association of Tuscany ModuleActivator and OSGi Bundle Activator
  • Make sure unique Bundle-SymbolicName
  • Avoid split java packages

Package all of the 3rd party jars as an OSGi bundle

Partially done. The following items remain:

  • Experiement one big bundle or multiple bundles
  • Resolve inconsistency between the maven-generated the .classpath and the Bundle-ClassPath entry

Provide a SCA node launcher to run SCA application with OSGi-enabled Tuscany runtime

The launcher now works with SCA node.
The following need to be supported as well:

  • SCA Domain Manager
  • NodeDaemon
  • Webapp-based launcher

Support different bundle packaging and distribution schemes (jars and class folders, distribution and Eclipse workspace)

Bring up the calculator sample with Equinox Node Launcher

Done

 

Bring up the calculator RCP with Eclipse Equinox

Under bring-up

Use the Import/Export packages for Tuscany modules to enforce the SPI contracts, Refactor SPIs if necessary, Split a few modules into model and runtime

Change how JDK factories are discovered and instantiated

Done for the core

Rationalize and clean up the SCA contribution classloading strategy

 

Convert samples and itests to use the OSGi-enabled Tuscany runtime

 

OSGi bundles as SCA contributions

Work Items

Status

Support packaging of SCA contributions as OSGi bundles

 

Support the OSGi import/export as SCA contribution import/export

 

Convert some samples or itests to use OSGi bundle as the SCA contributions

 

Integrate SCA assembly with OSGi services

Work Items

Status

First step: Define a set of scenarios to better understand the resulting programming model (OSGi + SCA)
Potentially implementation.osgi and Enterprise OSGi