OSGi enablement for Tuscany by yurtgc548


									OSGi Enablement for Apache
         Raymond Feng
• Provide modularity for Tuscany to
  formalize/enforce the SPI contracts and
  minimize the package dependencies across
• Enable Tuscany to work with OSGi environment
  such as JEE application servers, Eclipse RCP or
  Spring DM
• Provide versioning and isolation so that Tuscany
  extensions can depend on different versions of
  the same library
• Provide lifecycle management for extensions:
  install/uninstall/start/stop a module
• Tuscany runtime will be able to run in both
  non-OSGi and OSGi environment
  – No OSGi APIs should be used for non-OSGi
    specific modules
• Build a consistent OSGi story to facilitate
  developing, building, launching, running
  and testing Tuscany
  – Makes developers’ life a bit easier to work
    with OSGi
What problems do we try to solve?
• Turning Tuscany modules into OSGi
• Turning 3rd party dependencies into OSGi
• Developing, building, launching, running
  and testing with OSGi
• Producing distributions that are compatible
  with the OSGi bundle structure in an
  efficient way (in one-two minutes)
Turning Tuscany modules into
        OSGi bundles
    Creating bundles for Tuscany
• Modularize Tuscany after the maven modules
  – One OSGi bundle per maven module
  – Be consistent for build, packaging and runtime
  – Much easier to aggregating than decomposing
• Developers are responsible for authoring and
  maintaining MANIFEST.MF (instead of MF
  generation tools)
  – Tooling friendly
  – Developers pay more attentions to the dependencies
  Things to consider to create an
    OSGi bundle for a module
• Add META-INF/MANIFEST.MF (don’t stop
  here …)
• Clean up module dependencies and
  package visibilities
• Prepare for code changes
  – Service Discovery
  – ClassLoading
                   Rules of thumb
• Identify the absolutely necessary SPI packages that need to be
   – Don't try to export everything
   – For model modules, try to only export the package that contains the
   – Try not to export any package from the xxx-runtime moudles
   – Any classes that can be accessed via the ExtensionPointRegistry using
     interfaces should not be exported
• Only import other packages when it's needed
   – For example, we used to have a lot of modules pull in assembly for just
     a constant for the SCA namespace
   – Avoid DynamicImport-Package=*
   – Avoid Require-Bundle
• Do not export "private" packages as a workaround or hack which
  can fail the "clean SPI". Refactor things into SPIs if necessary
       Granularity Discussion
• 180+ bundles cumbersome
• Multiple bundles required to enable one
• Much debate about right level of granularity
  (flexibility vs. usability)
• Some opinions
  – Fine-grained bundles suitable for developer view
  – Features/Profiles used to “group” bundles to provide a
    user view
     • Inspired by Eclipse Features
Dealing with 3rd party jars
         Handling 3rd party jars
• We have to live with the reality:
   – Many 3rd party jars are not OSGi bundles. No repo is
     available to get all converted bundles
      • We need to convert them (build time, run time)
   – Some of the 3rd party bundles are broken (w/ bogus
      • We need to fix them (replacing the MF)
   – More and more 3rd party jars are upgraded to be
     OSGi bundles
      • We should be able to incrementally consume 3rd party jars as
        OSGi bundles
   Converting 3rd party jars to OSGi
• A folder bundle is created to represent a 3rd party jar
                               Bundle-Classpath: third-party.jar               MANIFEST
                               Dynamic-Import-Package: *                       Bundle-Classpath: third-party.jar
                                                                               Import-Package: ...
                               Export-Package: ...                             Export-Package: ...
                               ...                                             ...
     third-party.jar                                               Install
                                     third-party.jar                             third-party-osgi.jar

• The folder structure looks like:                                           OSGi Framework
    – jaxb-impl-2.1.12
          • META-INF
                 – MANIFEST.MF
          •   jaxb-impl-2.1.12.jar
• It is non-invasive and flexible
    – The original jar is not changed (avoid legal, signature issues)
    – Multiple jars can be easily aggregated (control the bundle granularity)
    – The MANIFEST.MF can be easily customized
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.sun.xml.bind.jaxb-impl
Bundle-Name: com.sun.xml.bind.jaxb-impl
Bundle-Version: 2.1.12
DynamicImport-Package: javax.transaction;version="1.1",javax.transacti
Bundle-ClassPath: jaxb-impl-2.1.12.jar
Export-Package: com.sun.xml.bind.v2.schemagen;version=2.1.12,com.sun.x
Developing Tuscany with
   Checking out source code and
       building with maven
• Check out the Tuscany source code from
  – svn co https://svn.apache.org/repos/asf/tuscany/java/sca/

• Run maven build
  – mvn clean install -fn

• Generate Eclipse projects
  – mvn -Peclipse
          Setting up Eclipse PDE
• Download Eclipse (w/ plugin development)
  –   http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/gal

• Configure PDE target platform
  – File  Open File
        • <tuscany>\sca\distribution\all\target\features\tuscany-
  – Click on “Set as target platform”
• Load Tuscany modules into Eclipse
  – File  Import …  General  Import Existing
    Projects …
     What’s happening during the
           Tuscany build?
• Validating OSGi constraints to report bundle resolution
  issues during compilation
• Generating PDE project so that Tuscany modules can be
  loaded in Eclipse to leverage the nice OSGi tooling
• Generating OSGi bundles for 3rd party jars
• Generating PDE target platform definitions so that 3rd
  party bundles can be used in Eclipse as plugin
• Generating Equinox configuration so that Tuscany
  distribution can be directly loaded as an OSGi framework
   Maven/OSGi Tools provided by
• Maven-bundle-plugin
  – Generates bundles for 3rd party jars
  – Generates OSGi enabled PDE projects
  – Version 1.0.4 released at 10/09/2009
• Maven-eclipse-compiler
  – Expose OSGi aware Eclipse JDT compiler
  – Expose Eclipse OSGi bundle validation
  – Version 1.0.1 released on 04/07/2009
• Maven-osgi-junit-plugin
  – JUnit tests in a OSGi enabled environment
  – Version 1.0 released on 10/28/2009
• https://svn.apache.org/repos/asf/tuscany/maven-
         Development Time
• Eclipse PDE provides nice OSGi tooling
  – Graphical editor for MANIFEST.MF (w/
    additional tools to analyze/calculate
  – Plugin Dependencies Classpath Container
  – Compilation errors/warning for OSGi
    constraint violations (w/ Quick Fix
  – OSGi test environment to validate and launch
    OSGi framework (w/ console)
• Provide a SCA node launcher to start an OSGi runtime
  and run SCA application with the OSGi-enabled Tuscany
• We need to use Tuscany's service discovery mechanism
  to discover and instantiate the factories
      • Change how JDK factories such as XMLInputFactory, XPathFactory, and
        DocumentBuilderFactory, are discovered and instantiated
      • XMLInputFactory.newInstance() used the JSE service provider pattern which
        doesn't work with OSGi
• Adjust the code that assumes there is a flat thread
  context classloader that can access all the classes in the
  Tuscany runtime
      • With OSGi, there is a network of classloaders (one classloader per module)
        and the class visibility is constrained by the OSGi headers such as Import-
        Package and Export-Package
      • The classloader for the current class is a good starting point for
        Class.forName() with OSGi
Launching OSGi framework within
          Eclipse PDE
 Launching OSGi from Tuscany distribution
• Equinox:
   –   java -jar osgi-3.5.0-v20090520.jar -clean -console -configuration ..\features\configuration

• http://cwiki.apache.org/confluence/display/TUSCANYxDOCx2x/Run
Testing Tuscany with OSGi
                    A few options
• Tuscany maven-osgi-junit plugin
   – Generate two bundles for the main and test classes respectively.
     The test bundle is a fragment of the main bundle.
       • For example, the plugin generates the following bundles for sample-
         calculator-osgi.jar: * sample-calculator-osgi-osgi.jar * sample-
   – Find the EquinoxHost class from tuscany-node-launcher-equinox
     and create an instance
   – Start the equinox runtime
   – Set up the classloader for surefire so that it uses OSGi
     classloading for the test cases with the test bundle.
   – Delegate to surefire to run the unit tests
• Apache Felix junit4osgi
   – http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html
Trouble-shooting OSGi related
                Common traps
• System packages need to be explicitly imported, such as
• Be careful of TCCL (ThreadContext Classloader)
   – No well-defined TCCL in OSGi
   – Equinox uses ContextFinder to find the closest class on
     the calling stack that is loaded by an OSGi bundle
   – JDK and some 3rd party libraries uses service
     discover pattern relying on TCCL being able to
     load/see everything
                  Some tips
• Most common exceptions:
  – ClassNotFoundException
  – NoClassDefFoundError
• Bundle is not resolved:
  – Missing Import-Package (including system packages
    from the JDK)
  – Split package from Export-Package
  – Different versions of the same package are exported
  – Chain of bundle resolution (Exported packages from
    unresolved bundle cannot be seen.)
                   Useful Links
• http://cwiki.apache.org/autoexport-
• Infoq.com articles:
  – http://www.infoq.com/articles/modular-java-what-is-it
  – http://www.infoq.com/articles/modular-java-static-modularity
  – http://www.infoq.com/articles/modular-java-dynamic-modularity

• http://www.dynamicjava.org/

To top