2016/05/28 - Apache Tuscany has been retired.

For more information, please explore the Attic.

HomeApache Tuscany Docs 2.x > Index > Development Guides > OSGi Aware Programming in Tuscany
 Apache Tuscany Docs 2.x > Index > Development Guides > OSGi Aware Programming in Tuscany Tuscany Home | User List | Dev List | Issue Tracker  
Table of Contents

Motivation for OSGi

The Apache Tuscany project has become a large project, with various extensions and component types that brings to the SCA Runtime different levels of dependencies. With its growth, Tuscany also started to have it's SPIs violated by some of these extensions, and some of the boundaries between sub-systems are broken, as there wasn't any enforcement of these boundaries.

The OSGi model provides a very powerful and flexible framework to develop applications in a modular fashion with a high degree of control over classloading inter-dependencies over modules. An OSGi module (a.k.a bundle) have a manifest file (META-INF\manifest.mf) that contains module information such as "name", "version" and also a list of what packages are being exported, and what packages are being imported from the given bundle, providing ways to easily enforce module boundaries.

In summary:

  • Better class loading mechanism for our modules
  • Create clean boundaries between sub-systems

Tuscany and OSGi - 3rd party dependencies

Currently we are wrapping the 3rd party dependencies as OSGi bundles, but leaving it unpacked (a.k.a folder structure). This allow use to use the same dependency jars in a OSGi environment as well as in a non-OSGI environment and generating no side effect on our distribution footprint.

Tuscany and OSGi - Granularity

The granularity used to define modules should be very familiar to all tuscany developers,

Tuscany Modules --> OSGi Bundles
3rd Party Libraries --> OSGi Bundles (using unpacked wrap style bundle)

Properly defining new Tuscany modules as an OSGi bundle

When adding new modules to the Tuscany project, the developer will need to create the OSGi Manifest to properly describe the new module as an OSGi bundle. These artifacts can be automatically generated using the Felix maven-bundle-plugin and should be available from svn repository once it's stable.

Generating OSGi manifest with Felix maven-bundle-plugin

"configuring maven to generate the OSGi manifest"
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <configuration>
        <instructions>
            <!-- Bundle versioned from Tuscany version -->
            <Bundle-Version>${tuscany.version}</Bundle-Version>
            <!-- Bundle Symbolic name -->
            <Bundle-SymbolicName>org.apache.tuscany.sca.api</Bundle-SymbolicName>
            <!-- Bundle description from pom description -->
            <Bundle-Description>${pom.description}</Bundle-Description>
            <!-- Export org.osoa.sca and all sub-packages -->
            <Export-Package>org.osoa.sca*</Export-Package>
            <!-- No Import-Package so calculate imports from code dependencies -->
        </instructions>
    </configuration>
</plugin>

Below is a manifest that was generated for one of the Tuscany modules using the felix maven-bundle-plugin.

"OSGi Manifest (META-INF\manifest.mf)"
Manifest-Version: 1.0
Export-Package: org.apache.tuscany.sca.assembly;uses:="javax.xml.xpath
 ,org.apache.tuscany.sca.assembly.impl,org.apache.tuscany.sca.policy,o
 rg.apache.tuscany.sca.interfacedef,javax.xml.namespace";version="1.4"
 ,org.apache.tuscany.sca.assembly.impl;uses:="javax.xml.xpath,org.apac
 he.tuscany.sca.assembly,org.apache.tuscany.sca.policy,org.apache.tusc
 any.sca.interfacedef,javax.xml.namespace";version="1.4",org.apache.tu
 scany.sca.assembly.builder;uses:="org.apache.tuscany.sca.assembly,org
 .apache.tuscany.sca.definitions,org.apache.tuscany.sca.core,org.apach
 e.tuscany.sca.monitor,org.apache.tuscany.sca.interfacedef,org.apache.
 tuscany.sca.extensibility";version="1.4"
Private-Package: org.apache.tuscany.sca.assembly.builder.impl;version=
 "1.4"
Tool: Bnd-0.0.255
Bundle-Name: Apache Tuscany SCA Assembly Model
Created-By: 1.6.0_07 (Sun Microsystems Inc.)
Bundle-Vendor: The Apache Software Foundation
Bundle-Version: 1.4
Bnd-LastModified: 1225397097203
Bundle-ManifestVersion: 2
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-Description: Apache Tuscany SCA Assembly Model
Import-Package: javax.xml.namespace,javax.xml.parsers,javax.xml.transf
 orm,javax.xml.transform.dom,javax.xml.transform.sax,javax.xml.xpath,o
 rg.apache.tuscany.sca.assembly;version="1.4",org.apache.tuscany.sca.a
 ssembly.builder;version="1.4",org.apache.tuscany.sca.assembly.impl;ve
 rsion="1.4",org.apache.tuscany.sca.core;version="1.4",org.apache.tusc
 any.sca.definitions;version="1.4",org.apache.tuscany.sca.extensibilit
 y;version="1.4",org.apache.tuscany.sca.interfacedef;version="1.4",org
 .apache.tuscany.sca.monitor;version="1.4",org.apache.tuscany.sca.poli
 cy;version="1.4",org.apache.tuscany.sca.policy.util;version="1.4",org
 .w3c.dom,org.xml.sax,junit.framework;resolution:=optional,org.apache.
 tuscany.sca.interfacedef.impl;version="1.4";resolution:=optional,org.
 junit;resolution:=optional
Bundle-SymbolicName: org.apache.tuscany.sca.assembly
Bundle-DocURL: http://www.apache.org/

Tweaking the OSGi manifest

Eclipse PDE provides good tooling for editing and maintaining OSGi manifest files. There are various scenarios we might need to tweak the OSGi manifest manualy :

  • Updating imported/exported packages
  • Marking test dependencies optional
    • Avoid issues when tests have references to external packages

PDE integration of tuscany modules

1) We generate the .classpath from maven dependencies.

2) For maven compile/provided dependencies, the modules explicit references
these dependencies via packages. We define corresponding Import-Package
header in the MANIFEST.MF for OSGi, and these get resolved to other bundles
that export the matching packages. This magic comes from the
"org.eclipse.pde.core.requiredPlugins" classpath container which is
contributed by the Eclipse PDE. The classpath container resolves the OSGi
dependencies such as Import-Package or Required-Bundle and automatically add
the required bundles to the classpath as we see in Eclipse project under the
"Plugin Dependencies".

3) The exported packages come from three types of sources:

  • System packages (exported by the System Bundle, i.e., org.eclipse.osgi).
    Different JDK levels have different list of system packages, for example,
    javax.xml.stream is not in J2SE-1.5 but in JSEJava-1.6. You can find the
    complete list by looking the .profile files within osgi-<version>.jar.
  • Tuscany modules in the Eclipse workspace. The classpath entry will be
    listed as a project under "Plugin Dependencies"
  • 3rd-party jars (already as OSGi bundles contributed by the target
    platform). The classpath entry will be listed as a jar under "Plugin
    Dependencies"

4) For maven runtime dependencies, there is no corresponding Import-Package
and the dependencies are used in runtime. Ideally in OSGi, they could be a
Required-Bundle or a bundle available at runtime. To run the project in JSE
inside Eclipse, we generate an explicit classpath entry.

5) For maven test dependencies, there are two types: one is for test
compilation and the other for test runtime. For the first type, we use
optional Import-Package to pull in the dependencies if the same project has
the compile dependency for the same artifact. Otherwise, we generate an
explicit classpath entry for JSE testing.

6) For test cases which require extra dependencies in addition to the
compile/provided/runtime dependencies for the main code, they probably
should not be unit tests. We need to consider how to move them into the
itest bucket.